线程调度、优先级、亲和力


1.挂起和恢复线程
  (1)ResumeThread
     被挂起的线程不会被调度,只有线程调用ResumeThread()的次数等于SuspendThread()时,线程才会被调度。  
  (2)SuspendThread
     当线程正在堆分配内存时(会给这个堆加上锁),此时如果将线程挂起,其它线程若想在堆上分配内存则会进入无限等待 直到堆的锁被挂起的线程解开。从而导致死锁。

Code

 

尽量不要在外面调用 SuspendThread 暂停线程,不要用 TerminateThread 结束线程

win32下的API基本都是线程安全的,因此API里面有很多线程同步的地方,LoadLibrary里面有一个临界区,线程函数在执行到LoadLibrary里面之后,如果刚好走到LoadLibrary的临界区里面,此时主线程的ontimer触发,将该线程挂起,ontimer继续执行,运行到LoadLibrary后,由于线程中LoadLibrary还没有从临界区出来,此时就造成主线程ontimer里面的LoadLibrary无限等待,主线程挂起。

因此不建议用suspend暂停线程,MSDN也有说明,suspend最好只在debug里面使用。

那怎么使线程挂起呢?可以使用事件等方式,用wait族函数来暂停线程


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)设置优先级      
     线程的优先级和进程的优先级是相关的。改变进程的优先级会同时改变线程的优先级。也可把进程的优先称做线程的基优先级。
     虽然进程有优先级但进程并不可调度,进程优先级只是种抽象的概念,帮助我们脱离调度器的内部工作原理。
              SetPriorityClassGetPriorityClass用来设置和获得进程的优先级。
              SetThreadPriorityGetThreadPriority用来设置和获得线程的优先级。
  (2)动态提升优先级
     默认情况下Windows会动态提升一些线程或进程的优先级从而避免当高线程优先级垄断CPU. 提高低线程的优先级让它获取CPU.当线程执释放CPU时会立刻降到原来的优先级。
     设置或获取线程或进程的动态优先级设置。从而许或禁止系统动态提升优先级
              SetProcessPriorityBoostSetThreadPriorityBoost
              GetProcessPriorityBoostGetThreadPriorityBoost 
                              
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()

 

 

你可能感兴趣的:(优先级)