Windows编程——线程篇(一):线程简介

文章目录

  • Windows编程——线程篇(一):线程简介
    • 线程的启动
    • 线程的终止
    • 线程终止时发生的事情
    • 线程的调度
    • 查看内核线程的状态
    • 线程 优先级
      • 设置进程优先级
      • 设置线程优先级

Windows编程——线程篇(一):线程简介

线程由2部分构成:线程的内核对象和线程堆栈。操作系统使用内核对象对线程进行管理,堆栈则用于维护线程在执行代码时需要的所有函数参数和局部变量。一个进程中的多个线程之间共享这个进程的代码段、地址空间、内核对象句柄等。

线程的启动

可以使用createthread、__beginthread函数来创建一个线程。但是一般建议使用beginthread,虽然它也是调用的createthread函数来创建线程的。但是beginthread会另外初始化C运行时库,保证C库的线程安全。比如errno一般是全局共享的,如果使用createthread则所有线程都共享这一个errno,但是如果使用beginthread则每个线程都有自己的errno不会互相影响。

HANDLE CreateThread(
    LPSECURITY_ATTRIBUTES lpThreadAttributes,
    SIZE_T dwStackSize,
    LPTHREAD_START_ROUTINE lpStartAddress,
    LPVOID lpParameter,
    DWORD dwCreationFlags,
    LPDWORD lpThreadId
    );
    
uintptr_t _beginthread(
    _beginthread_proc_type _StartAddress,
    unsigned               _StackSize,
    void*                  _ArgList
    );
uintptr_t _beginthreadex(
    void*                    _Security,
    unsigned                 _StackSize,
    _beginthreadex_proc_type _StartAddress,
    void*                    _ArgList,
    unsigned                 _InitFlag,
    unsigned*                _ThrdAddr
    );

线程的终止

  • 它所在的进程终止
  • 从线程执行函数返回
  • 在线程函数中调用exitthread线程自行销毁
  • 其他线程或进程调用terminatethread

线程终止时发生的事情

  • 线程所拥有的用户对象被释放
  • 线程内核对象的状态变为已知
  • 如果现成是进程中最后一个活动现成,那么进程也将终止
  • 线程内核对象的引用计数-1

线程的调度

暂停和重启线程

DWORD SuspendThread(HANDLE hThread);
DWORD ResumeThread(HANDLE hThread);

睡眠

VOID Sleep(DWORD dwMilliSeconds);
  • sleep函数使调用它的线程自愿放弃剩余的CPU时间片
  • 系统将在指定的时间内使线程不可调度

转换到另一线程

// 转换到另一线程运行
BOOL SwithToThread();

线程的运行时间

单纯的使用GetTimeTick获取时间差并不可靠,因为线程可能被中断,可能被挂起,也可能退出。为了获得线程具体的运行时间,可以通过getthreadtimes:

BOOL GetThreadTimes(
	HANDLE hThread,
    PFILETIME pftCreationTime,// 线程创建时间
    PFILETIME pftExitTime,// 线程退出时间,如果正在运行则未定义
    PFILETIME pftKernelTime,// 线程内核态运行时间
    PFILETIME pftUserTime // 线程用户态运行时间
);

BOOL GetProcessTimes(
	HANDLE hThread,
    PFILETIME pftCreationTime,
    PFILETIME pftExitTime,// 
    PFILETIME pftKernelTime,// 
    PFILETIME pftUserTime // 
);


// 频率*计数就是运行时间
BOOL QueryPerformanceFrequency(LARG_INTERGER *pliFrequence);
BOOL QueryPerformanceCounter(LARG_INTERGER *pliCounter);

查看内核线程的状态

BOOL GetThreadContext(
	HANDLE hThread,
    PCONTEXT pContext;
);

线程 优先级

线程优先级从0(最低)~31(最高),系统调度的时候总是先调度优先级高的线程,除非优先级高的线程不存在则调度优先级低的线程。Windows支持6个应用程序优先级:

优先级 描述
实时 进场中的线程必须立即对事件做出相应,以便执行关键事件的任务。该进场中的线程还会抢先于操作系统组件之前运行,使用本优先级时必须极端小心
进场中的线程必须立即对时间做出相应,task manager(任务管理器)在这个级别上运行,以便用户可以撤销脱离控制的程序
高于正常 进场中的线程在正常优先级与高优先级之间运行
正常 正常,没有特殊的调度需求
低于正常
空闲 进场中的线程在系统空闲时运行。该进程通常由屏幕保护程序或者后台实用程序和搜集统计数据的软件使用

应该尽可能避免使用实时优先级类。实际上Windows NT 3.1的早期测试版并没有向应用程序展示这个优先级类,尽管该操作系统支持这个类。实时优先级是很高的优先级它可能干扰操作系统任务的运行,因为大多数操作系统线程均以较低的优先级来运行。

设置进程优先级

BOOL SetPriorityClass(HANDLE hProcess,DWORD fdwPriority);
DWORD GetPriorityClass(HANDLE hProcess);

// 进程优先级类标识符
//实时:REALTIME_PRIORITY_CLASS
//高:HIGH_PRIORITY_CLASS
//高于正常:ABOVE_NORMAL_PRIORITY_CLASS
//正常:NORMAL_PRIORITY_CLASS
//低于正常:BELOW_NORMAL_PRIORITY_CLASS
//空闲:IDLE_PRIORITY_CLASS

设置线程优先级

BOOL SetThreadPriority(HANDLE hThread,DWORD fdwPriority);
DWORD GetThreadPriority(HANDLE hThread);

// 进程优先级类标识符
//实时:THREAD_PRIORITY_TIME_CRITICAL
//最高:THREAD_PRIORITY_HIGHEST
//高于正常:THREAD_PRIORITY_ABOVE_NORMAL
//正常:THREAD_PRIORITY_NORMAL
//低于正常:THREAD_PRIORITY_BELOW_NORMAL
//空闲:THREAD_PRIORITY_IDLE

你可能感兴趣的:(Windows编程,windows编程,多线程)