(1)ResumeThread
被挂起的线程不会被调度
(2)SuspendThread
当线程正在堆分配内存时(会给这个堆加上锁),
Code
SuspendThread和ResumeThread的作用其实很简单,他们都是通过线程的HANDLE到线程的数据结构中将一个计数的变量(只有一个BYTE大小的int变量)进行加一减一的操作,可以简单的认为
DWORD SuspendThread(HANDLE hThread)
{
nThreadSuspendCount ++;
}
DWORD ResumeThread(HANDLE hThread)
{
nThreadSuspendCount --;
}
(当然实际不会只有上面那么简单,还会有许多判断,包括BYTE的溢出监测、读写独占控制等)
如果线程在运行时监测到nThreadSuspendCount > 0,那么线程就会暂停处理任何消息和循环的进行,这时CPU将不为该线程分配时间片,如果nThreadSuspendCount <= 0,线程将正常运行!
所以ResumeThread的一次调用并不一定导致线程的运行,SuspendThread也不一定导致线程挂起,关键在于线程的挂起计数!
尽量不要在外面调用 SuspendThread 暂停线程,不要用 TerminateThread 结束线程
win32下的API基本都是线程安全的,因此API里面有很多线程同步的地方,LoadLibrary里面有一个临界区,线程函数在执行到LoadLibrary里面之后,如果刚好走到LoadLibrary的临界区里面,此时主线程的ontimer触发,将该线程挂起,ontimer继续执行,运行到LoadLibrary后,由于线程中LoadLibrary还没有从临界区出来,此时就造成主线程ontimer里面的LoadLibrary无限等待,主线程挂起。
因此不建议用suspend暂停线程,MSDN也有说明,suspend最好只在debug里面使用。
那怎么使线程挂起呢?可以使用事件等方式,用wait族函数来暂停线程
Windows中并不存在挂起和恢复进程的概念。因为
我们可以把挂起进程理解为挂起进程中所有的线程。
CreateToolhelp32Snapshot只是创建某个进程在某一时刻的快照
这么做容易出一些问题
(1)Sleep
线程调用
Sleep(0)的意思是让当前线程让出
(2)SwitchThread
与
不同的是
(1)设置优先级
线程的优先级和进程的优先级是相关的。改变进程的优先级会同时改变线程的优先级。也可把进程的优先称做线程的基优先级。
虽然进程有优先级但进程并不可调度,进程优先级只是种抽象的概念,帮助我们脱离调度器的内部工作原理。
SetPriorityClass和
SetThreadPriority和
(2)动态提升优先级
默认情况下
设置或获取线程或进程的动态优先级设置。从而允许或禁止系统动态提升优先级。
SetProcessPriorityBoost,
GetProcessPriorityBoost,
SetProcessAffinityMask 限制某进程中的线程
SetThreadAffinityMask 限制线程只能在指定的
GetSystemInfo() 查看
DWORD ResumeThread(HANDLE hThread);
DWORD SuspendThread(HANDLE hThread);
CreateToolhelp32Snapshot()
Thread32First()
Thread32Next()
Sleep()
GetThreadContext()
SetThreadContext()