Windows Via C/C++:线程的挂起和恢复

使用CreateThread函数创建线程或CreateProcess创建进程时,系统会创建线程/主线程内核对象,并将其中的暂停计数(suspend count)置为1,这样CPU调度程序会认为该内核对象不可调度,线程得以完成其初始化。初始化完成后,CreateThread/CreateProcess函数检查调用者是否传递了CREATE_SUSPENDED标志,若是,CreateThread/CreateProcess函数返回,线程依然处于挂起状态,否则,函数将调整线程内核对象的暂停计数值为0,此时该对象变为可调度对象(除非它在等待某事件的发生)。

创建挂起的线程允许调用者在线程执行之前更改其属性(如优先级),做完必要的更改之后,必须调用ResumeThread函数恢复线程状态,使其变为可调度的:
DWORD ResumeThread(HANDLE hThread);
参数hThread是要恢复的线程内核对象的句柄。ResumeThread调用成功时返回线程旧的暂停计数,否则返回0xFFFFFFFF。

一个线程可以挂起多次(假设为N),如果要将其恢复为可调度的,必须对其调用N次ResumeThread。除了在创建线程时指定CREATE_SUSPENDED标志,还可以调用SuspendThread挂起已存在的线程:
DOWRD SuspendThread(HANDLE hThread);
任何线程都可以调用SuspendThread挂起别的线程,甚至是挂起自己,但要注意线程挂起自己之后本身是无法恢复的。一个线程最多可以被挂起MAXIMUM_SUSPEND_COUNT(在WinNT.h中该值被定义为127)次。此外,SuspendThread对内核模式而言是异步的,对用户模式则是同步的。

开发人员在使用SuspendThread必须非常谨慎,因为要挂起的线程在SuspendThread发生时的动作是不可预测的,比如线程在请求从堆中分配内存时被挂起,此时线程已经给堆加了锁,那么其它线程对堆的请求将被阻塞,直到原线程恢复。

你可能感兴趣的:(windows)