线程二

来源:互联网 发布:java用正则表达式 编辑:程序博客网 时间:2024/04/30 09:56

一、线程的调度     

   window是抢占式多线程操作系统,也就是说一个线程可以随时停止运行,即不管这个线程是否已经消耗完自己的时间片,随后另一个线程可进行调度。线程的内核对象中使用线程上下文结构(CONTEXT结构)来保存自己线程运行时的CPU寄存器状态,当线程切换时,都会进行线程上下文切换。

       在线程的内核对象中设定了一个暂停计数。当调用CreateProcess或CreateThread函数时,会创建一个线程内核对象,并且将暂停计数设为1,这样就可以阻止线程被调用到CPU,这样就可以有时间初始化线程。当线程初始化完成后,CreateProcess或CreateThread函数会查看是否传递了CREATE_SUSPENDED标志。如果传递了,那么函数就会返回,线程保持暂停状态;如果没有传递该标志,那么暂停计数就会变为0,线程就会处于可调度状态(除非线程正在等待其他事情)。

        当线程处于暂停状态时,如果我们需要将线程设为可调度状态,那么可以用函数ResumeThread函数来实现。这个函数没执行一次,暂停计数会减1次,只有暂停计数为0,线程就可以处于可调度装填。该函数成功执行成功,会返回前一个暂停计数,否则,返回0XFFFFFFF。该函数如下:

     DWORD ResumeThread(HANDLE hThread);

        除了使用CREATE_SUSPENDED标志外,还可以使用函数SuspendThread来暂停线程。每次调用该函数,暂停计数都会加1。任何线程够可以使用该函数来暂停另一个线程,每个线程最多可以暂停次数为MAXIMUM_SUSPEND_COUNT(在WinNT.h中定义为127)。
        可以调用Sleep函数让线程在某个时间段内不被调用,其形式如下:

     VOID Sleep(DWORD dwMilliseocnds);

       关于Sleep函数,有下面几个问题值得注意:

  • 调用Sleep函数,会自愿放弃它剩余的时间片。
  • 系统将在大约的指定毫秒数内使线程不可调用。
  • dwMilliseocnds如果设为INFINITE时,表示该线程永远不会被调用。
  • dwMilliseocnds如果设为0,表示线程会放弃剩余的时间片,当会处于可调度状态。

        可以调用SwitchToThread函数判断是否有一个急需CPU的线程,如果有,就会对该线程调用,如果没有,就会继续系统调用。其形式如下:

     BOOL SwitchToThread();

        可以使用函数GetThreadTimes和GetProcessTimes来获取线程和进程的运行时间:

    BOOL GetThreadTimes( HANDLE hThread, PFILETIME pftCreationTime, PFILETIME pftExitTime, PFILETIME pftKernelTime, PFILETIME pftUserTime);     BOOL GetProcessTimes( HANDLE hProcess, PFILETIME pftCreationTime, PFILETIME pftExitTime, PFILETIME pftKernelTime, PFILETIME pftUserTime);

           windows还提供了用于高分辨率性能的函数:

       BOOL QueryPerformanceFrequency(LAGE_INTEGER *pliFequency);       BOOL QueryPerformanceFCounter(LAGE_INTEGER *pliCount);

           CONTEXT结构对于不同的CPU成员有不同,我们可以通过GetThreadContext函数来获取线程内核对象CONTEXT结构,可以通过SetThreadContext函数对CONTEXT结构进行设置:

       BOOL GetThreadContext(HANDLE hThread,PCONTEXT pContext);             BOOL SetThreadContext(HANDLE hThread,const PCONTEXT pContext);

二、线程的优先级

       在windows中每个线程都被赋予一个0到31的优先级。高优先级的可调度的线程优先被调用。高优先级的线程抢在低优先级的线程前运行,不管这个低优先级的线程的时间片是否用完。在windows中只有一个唯一的0优先级线程,称为0页线程。该线程在系统没有线程运行时,该线程将系统中的所有空闲RAM页面置为0。

       windows的调用算法是变化的,因此在编写程序时要注意。

       windows的线程优先级由进程的优先级类和相对的线程优先级来决定的。进程的优先级类有6个:空闲、低于正常、正常、高于正常、高和实时。windows支持7个相对的线程优先级:空闲、最低、低于正常、正常、高于正常、最高和关键时间优先级。

        windows负责将进程的优先级类和相对的线程优先级映射到具体的一个优先级上(0~31)。不同版本的映射方式可能是变化的,不是一成不变的。

       程序中可以使用SetPriorityClass和GetPriorityClass函数来设置和获取进程的优先级类,windows运用下面的标识符来代表各种优先级类:

    

sd

         BOOL SetPriorityClass(HANDLE hProcess,DWORD fdwPriority);         DWORD GetPriorityClass(HANDLE hProcess);

        当一个进程创建时,它的线程的相对线程优先级总是设置为正常,我们可以通过函数SetThreadPriority和GetThreadPriority来设置和获取相对的线程优先级。    

         BOOL SetThreadPriority(HANDLE hThread,int nPriority);         int GetThreadPriority(HANDLE hThread);

sd

        通过将线程的相对优先级和进程的优先级类综合考虑,我们就能够确定线程的优先级了。但,有时候线程会动态提高我们线程的优先级,以便我们队窗口消息或读取磁盘等I/O事件作出响应;另一个就是一个线程在长时间无法运行时,也会提高线程的优先级。    

        我们可以通过函数来对提高优先级的开关就行管理。SetProcessPriorityBoost函数可以激活或停用进程中所有线程的优先级提高功能;SetThreadPriorityBoost  函数可以激活或停用一个线程的优先级提高功能:

         BOOL SetProcessPriorityBoost(HANDLE hProcess,BOOL DisablePriorityBoost);        BOOL SetThreadPriorityBoost(HANDLE hThread,BOOL DisablePriorityBoost);

        也可以通过函数来获取是否设置了优先级提高功能:

         BOOL GetProcessPriorityBoost(HANDLE hProcess,BOOL DisablePriorityBoost);        BOOL GetThreadPriorityBoost(HANDLE hThread,BOOL DisablePriorityBoost);

三、线程的亲缘性
       在windows2000中,系统将线程分配处理器时,使用软亲缘性:在其他因素相同的情况下,会设法将线程分配给上次运行的处理器,这样就能够使用上次使用的高速缓存。

    我们可以通过硬亲缘性来控制哪个CPU能够运行某个线程。

    可以通过函数SetProcessAffinityMask来控制进程中的所有线程的运行CPU,通过函数GetProcessAffinityMask来获取进程中线程可以运行的CPU:

       BOOL SetProcessAffinityMask(HANDLE hProcess,DWORD_PTR pdwProcessAffinityMask);       BOOL GetProcessAffinityMask(HANDLE hProcess,PDWORD_PTR dwProcessAffinityMask,PDWORD_PTR pdwSystemAffinityMask); 

         可以通过函数SetThreadAffinityMask函数来设置线程的亲缘性:       

        DWORD_PRT SetThreadAffinityMask(HANDLE hThread,DWORD_PTR dwThreadAffinityMask); 

         可以通过函数SetThreaIdealProcessor来设置线程的理想CPU(尽可能运行在该CPU):

        DWORD SetThreaIdealProcessor(HANDLE hThread,DWORD dwIdealProcessor);       
原创粉丝点击