windows核心编程(第五版)笔记第七章线程调度优先级(threadsched
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Windows核心编程(第五版)笔记第七章线程调度、优先
级(Thread Sched...
Windows核心编程(第五版)笔记第七章线程调度、优先级(Thread Scheduling,Priorities and Affinity)
第七章线程调度、优先级、亲和力
1.挂起和恢复线程
(1)ResumeThread
被挂起的线程不会被调度,只有线程调用ResumeThread()的次数等于SuspendThread()时,线程才会被调度。
线程可以Suspend自已但是不能Resume自已。因为被挂起后不会被调度,从而不会执行线程函数内的代码.
(2)SuspendThread
挂起线程时一定要小心必须明确知道线
程在干什么才能决定是否挂起线程。因为当线程正在堆分配内存时,它会给这个堆加上锁。
此时如果将线程挂起,其它线程若想在堆上分配内存则会进入无限等待直到堆的锁被挂起的线程解
开。从而导致死锁。
2.挂起和恢复进程
Windows中并不存在挂起和恢复进程的概念。因为Windows中是以线程为单位来调度和分配CPU的。进程只相当于是一个承载线程的容器,系统不会给进程分配
任何CPU.
我们可以把挂起进程理解为挂起进程中所
有的线程。Windows并没有提供此类API,但是我们可以通过CreateToolhelp32Snapshot()来实现我们自制的SuspendProcess().
因为CreateToolhelp32Snapshot只是创建某
个进程在某一时刻的快照(如进程占有的内存,进程中有多少正在运行的线程)。
然后通过Thread32First()和Thread32Next()
来遍历快照中所得的所有线程。
这么做容易出一些问题比如通过
Thread32Next()取得线程ID后线程可能立刻就终止了。同样随时会有新的线程产生,而快照中不会反应有出新产生的线程,
从而也就无法挂起该线程。
3.Sleep和SwitchThread
(1)Sleep
线程调用Sleep函数后会进入睡眠状态系统会不调度该进程。
Sleep(0)的意思是让当前线程让出CPU给同或高优先级线程用,但不会把CPU让给比优先级低级的线程。
(2)SwitchThread
与Sleep(0)相同,SwitchThread会迫使当前线程让出CPU级其它线程用。若无其它线程则该函数立即返回。
不同的是SwitchThread允许低优先级的线程使用CPU.
4.优先级
(1)设置优先级
线程的优先级和进程的优先级是相关的。改变进程的优先级会同时改变线程的优先级。也可把进程的优先称做线程的基优先级。
虽然进程有优先级但进程并不可调度,进程
优先级只是种抽象的概念,帮助我们脱离调度器的内部工作原理。
SetPriorityClass和GetPriorityClass用来设置和获得进程的优先级。
SetThreadPriority和GetThreadPriority用来设置和获得线程的优先级。
(2)动态提升优先级
默认情况下Windows会动态提升一些线程或进程的优先级从而避免当高线程优先级垄断CPU.
提高低线程的优先级让它获取CPU.当线程执释放CPU时会立刻降到原来的优先级。
我们可以能过以下方法来设置或获取线程或进程的动态优先级设置。从而允许或禁止系统动态提升优先级。
SetProcessPriorityBoost,SetThreadPriorityBoost
GetProcessPriorityBoost,GetThreadPriorityBoost
a thread is not allowed to change the I/O
priority of another thread.
Code example:
DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL, 0, ThreadFunc,
NULL,CREATE_SUSPENDED, &dwThreadID);
SetThreadPriority(hThread, THREAD_PRIORITY_IDLE);
ResumeThread(hThread);
CloseHandle(hThread);
5.Affinity
SetProcessAffinityMask 限制某进程中的线程只能在指定的几个CPU上运行。也用通过Job内核对象限制Job中的所有进程只能在指定的CPU上运行。
SetThreadAffinityMask 限制线程只能在指
定的CPU上运行。其被指定的CPU必须是进程所指定的CPU的子集。
GetSystemInfo() 查看CPU信息
mon API:
DWORD ResumeThread(HANDLE hThread);
DWORD SuspendThread(HANDLE hThread);
CreateToolhelp32Snapshot()
Thread32First()
Thread32Next()
Sleep()
GetThreadContext()
SetThreadContext()