lgxqf  

第七章 线程调度、优先级、亲和力

 

1.挂起和恢复线程

              (1)ResumeThread

            被挂起的线程不会被调度,只有线程调用ResumeThread()的次数等于SuspendThread()时,线程才会被调度。

            线程可以Suspend自已但是不能Resume自已。因为被挂起后不会被调度,从而不会执行线程函数内的代码.

 

              (2)SuspendThread

              挂起线程时一定要小心 必须明确知道线程在干什么才能决定是否挂起线程。因为当线程正在堆分配内存时,它会给这个堆加上锁。

              此时如果将线程挂起,其它线程若想在堆上分配内存则会进入无限等待 直到堆的锁被挂起的线程解开。从而导致死锁。

 

2.挂起和恢复进程             

             

              Windows中并不存在挂起和恢复进程的概念。因为Windows中是以线程为单位来调度和分配CPU的。进程只相当于是一个承载线程的容器,系统不会给进程分配任何CPU.

             

              我们可以把挂起进程理解为挂起进程中所有的线程。Windows并没有提供此类API,但是我们可以通过CreateToolhelp32Snapshot()来实现我们自制的SuspendProcess().

              因为CreateToolhelp32Snapshot只是创建某个进程在某一时刻的快照(如进程占有的内存,进程中有多少正在运行的线程)

              然后通过Thread32First()Thread32Next()来遍历快照中所得的所有线程。

              这么做容易出一些问题 比如通过Thread32Next()取得线程ID后 线程可能立刻就终止了。同样随时会有新的线程产生,而快照中不会反应有出新产生的线程,

                 从而也就无法挂起该线程。

 

3.SleepSwitchThread

              (1)Sleep

              线程调用Sleep函数后会进入睡眠状态 系统会不调度该进程。

              Sleep(0)的意思是让当前线程让出CPU给同或高优先级线程用,但不会把CPU让给比优先级低级的线程。

 

              (2)SwitchThread

              Sleep(0)相同,SwitchThread会迫使当前线程让出CPU级其它线程用。若无其它线程则该函数立即返回。

              不同的是SwitchThread允许低优先级的线程使用CPU.

 

4.优先级

              (1)设置优先级      

              线程的优先级和进程的优先级是相关的。改变进程的优先级会同时改变线程的优先级。也可把进程的优先称做线程的基优先级。

              虽然进程有优先级但进程并不可调度,进程优先级只是种抽象的概念,帮助我们脱离调度器的内部工作原理。

 

              SetPriorityClassGetPriorityClass用来设置和获得进程的优先级。

              SetThreadPriorityGetThreadPriority用来设置和获得线程的优先级。

             

              (2)动态提升优先级

              默认情况下Windows会动态提升一些线程或进程的优先级从而避免当高线程优先级垄断CPU.

              提高低线程的优先级让它获取CPU.当线程执释放CPU时会立刻降到原来的优先级。

              我们可以能过以下方法来设置或获取线程或进程的动态优先级设置。从而允许或禁止系统动态提升优先级。

              SetProcessPriorityBoostSetThreadPriorityBoost

              GetProcessPriorityBoostGetThreadPriorityBoost

             

              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信息 

 

 

6.Common API:

 

              DWORD ResumeThread(HANDLE hThread);

              DWORD SuspendThread(HANDLE hThread);

              CreateToolhelp32Snapshot()

              Thread32First()

              Thread32Next()

              Sleep()

              GetThreadContext()

            SetThreadContext()

posted on 2009-02-15 21:13  Justin_Ma  阅读(870)  评论(0编辑  收藏  举报