转自:http://www.cnblogs.com/wz19860913/archive/2008/08/04/1259807.html


  每个线程都有一个“优先级”,范围是0~31,0为最低优先级,31为最高优先级。当系统决定哪个线程需要调度的时候,首先查看是否存在优先级为31的可调度线程,如果存在,就从中选择一个进行调度。当该线程的时间片到达之后,系统查看是否存在另一个优先级为31的可调度线程,如果存在,就调度它。

  只要有一个可调度的优先级为31的线程存在,那么系统绝对不会调度优先级为0~30的线程,这样会导致其他线程“饥饿”。

  高优先级线程往往“打断”低优先级线程的执行。比如,当一个优先级为15的线程正在运行,如果此时系统发现一个优先级比15高的线程可以调度,那么该高优先级线程会“打断”那个低优先级线程的执行,哪怕低优先级的时间片才过了一半。

  另外,当系统引导的时候,系统创建一个特殊的线程,称为“zero page”(0页)线程,该线程是整个系统中唯一一个优先级为0(最低)的线程。当系统没有任何线程需要执行的时候,该线程负责将系统中所有RAM页面清零(也就是资源回收)。

  线程优先级有一个抽象层的概念。

  由于一些历史的原因,微软并没有将线程调度程序的行为完全固定下来。微软没有让应用程序充分利用调度程序的特性。微软宣称这个调度程序的行为是变化,在编程的时候需要注意。

  由这几点可见,你的应用程序可以有自己的调度特性。

  Windows API充分反映了系统调度的一个抽象层。如此,就不会直接与系统的调度程序通信,相反,可以调用API函数,根据系统的版本的不同转换这些参数。这一层,就是线程优先级的抽象层。

  下面详细叙述这个抽象层究竟有哪些内容:

  对于进程而言,Windows有一个“优先级类”的概念。这些优先级类作用与进程中的所有线程。Windows 2000/XP/2003/Vista支持6个“优先级类”:

1、Real-time:实时

2、High:高

3、Above normal:高于标准

4、Normal:标准

5、Below normal:低于标准

6、Idle:空闲。

  一个进程应该避免使用“实时”优先级类,因为使用该优先级类会导致其他进程中的线程很难被调度,甚至会打断或者抢占系统线程的执行。“高”优先级类也应该尽量避免,除非有特殊的工作需要使用这个优先级。

  当一个进程的“优先级类”被确定以后,就只需要考虑该进程内部各个线程之间的优先级关系。

  对于进程中的线程而言,有一个“相对线程优先级”的概念,这可以决定一个进程中多个线程之间的优先级关系。

  Windows支持7种“相对线程优先级”:

1、Time-critical:关键时间(最高的相对线程优先级)

2、Heightest:最高(翻译是这么翻译,但是并不是最高的相对线程优先级)

3、Above normal:高于标准

4、Normal:标准

5、Below normal:低于标准

6、Lowest:最低(翻译是这么翻译,但是并不是最低的相对线程优先级)

7、Idle:空闲

  这里并没有提到有关0~31的优先级的任何内容。开发者从来不用具体设置一个线程的优先级,也就是不需要将一个线程优先级设置为0~31中的一个。操作系统负责将“优先级类”和“相对线程优先级”映射到一个具体的优先级上。这种映射方式,是随Windows版本的不同而不同的。

  以下是Windows 2000/XP/2003/Vista的线程优先级映射方式(书上只说是Vista,但是对比本书第四版,可知2000和Vista是一样的):

线程相对

优先级

进程优先级类

Idle

Below Normal

Normal

Above Normal

High

Real-Time

Time-critical

15

15

15

15

15

31

Highest

6

8

10

12

15

26

Above normal

5

7

9

11

14

25

Normal

4

6

8

10

13

24

Below normal

3

5

7

9

12

23

Lowest

2

4

6

8

11

22

Idle

1

1

1

1

1

16

  仔细查看该表,现在知道为什么最好不要将“进程优先级类”设置为“实时”了吧,因为一个进程如果具有“实时”的优先级类,那么该进程中的所有线程的优先级(最低也有16)比任何具有其他优先级类的进程中的线程的优先级(最高只有15)都要高。这样会导致其他优先级类低于“实时”的进程中的线程无法得到调度。

  要注意的是,“优先级类”是一个抽象的概念,是对于一个进程而言的,但是不是说进程是可以调度的,只有线程是可以调度的。微软提出这个概念,仅仅只是为了帮助你将它与调度程序的内部运行的情况区分起来。“优先级类”应该是可以影响一个进程中所有线程的优先级的。

  上面讲了有关线程优先级的内容,包括线程的“具体优先级”,“优先级抽象层”的内容(进程“优先级类”、“线程相对优先级”等)。

  下面主要讲述如何在编程中设置线程的优先级:

  一个进程,往往关联一个“优先级类”,你可以在CreateProcess函数的fdwCreate参数中设置这个优先级类的具体内容,可以有6种选择,对于6种优先级类:

1、REALTIME_PRIORITY_CLASS:Real-time,实时优先级类

2、HIGH_PRIORITY_CLASS:High,高优先级类

3、ABOVE_NORMAL_PRIORITY_CLASS:Above normal,高于标准

4、NORMAL_PRIORITY_CLASS:Normal,标准

5、BELOW_NORMAL_PRIORITY_CLASS:Below normal:低于标准

6、IDLE_PRIORITY_CLASS:Idle,空闲

  你也可以更改一个特定的进程优先级类,通过呼叫SetPriorityClass函数可以到达这个目的。

BOOL SetPriorityClass(
HANDLE hProcess, //指定的进程句柄
DWORD fdwPriority); //优先级类(对应上面6种取值)

  例如,下面的代码设置当前进程的优先级类为空闲:

SetPrioriytClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);

  当然,可以获得某一个进程的优先级类,通过呼叫GetPriorityClass函数:

DWORD GetPriorityClass(HANDLE hProcess);

  该函数返回的值就是对应6个优先级类的值中的一个。

  当一个线程被创建,它的“线程相对优先级”默认为normal(标准)。CreateThread函数没有提供设置线程相对优先级的功能。可以调用SetThreadPriority函数设置一个线程的相对优先级。

BOOL SetThreadPriority(
HANDLE hThread, //指定的线程句柄
int nPriority); //线程相对优先级(取值对应如下)

  该函数接受一个线程句柄和线程相对优先级取值,设置对应的线程的相对优先级。该线程相对优先级取值如下:

1、THREAD_PRIORITY_TIME_CRITICAL:Time-critical,关键时间(最高)

2、THREAD_PRIORITY_HIGHEST:Highest,最高(其实是“次高”)

3、THREAD_PRIORITY_ABOVE_NORMAL:Above normal,高于标准

4、THREAD_PRIORITY_NORMAL:Normal,标准

5、THREAD_PRIORITY_BELOW_NORMAL:Below normal,低于标准

6、THREAD_PRIORITY_LOWEST:Lowest,最低(其实是“次低”)

7、THREAD_PRIORITY_IDLE:Idle,空闲(最低)

  你可以呼叫GetTreadPriotiry函数取得一个特定线程的相对优先级。

int GetThreadPriority(HANDLE hThread);     //函数返回上述7个取值

  为了创建一个线程相对优先级不是标准的线程,比如要创建一个高于标准的线程,你可以传递CREATE_SUSPENDED参数给CreateThread,从而创建一个起始状态为“挂起”的线程,然后调用SetThreadPriority函数设置该线程的相对优先级,然后调用ResumeThread函数恢复该线程的运行。代码如下:

DWORD dwThreadID;
HANDLE hThread = CreateThread(NULL, , ThreadFunc, NULL, CREATE_SUSPENDED, &dwThreadID);
SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
ResumeThread(hThread);
CloseHandle(hThread);

  操作系统会动态地提高线程的基础优先级等级(0~31),一般是为了响应一些I/O事件。

  有的时候,系统动态地提高线程优先级会带来不便。你可以呼叫SetProcessPriorityBoost和SetThreadPriorityBoost函数来通知系统是否需要动态提高线程优先级。

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

  这两个函数的第二个参数用于通知系统是否要动态提高指定进程的优先级类和指定线程的相对优先级。

  也可以使用以下两个函数得到这些信息:

BOOL GetProcessPriorityBoost(HANDLE hProcess, PBOOL pbDisablePriorityBoost);
BOOL GetThreadPriorityBoost(HANDLE hThread, PBOOL pbDisablePriorityBoost);

<<Windows via C/C++>>学习笔记 —— 线程优先级【转】的更多相关文章

  1. [转]Windows平台下Makefile学习笔记

    Windows平台下Makefile学习笔记(一) 作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译 ...

  2. <转>Windows平台下Makefile学习笔记(二)

    本文转自:http://blog.csdn.net/clever101/article/details/8286066 上次我们学习了怎么用Makefile编译一个控制台工程.这次我们学习一下如何使用 ...

  3. Windows Internals 笔记——线程优先级

    1.每个线程都被赋予0(最低)~31(最高)的优先级数.当系统确定给哪个线程分配CPU时,它会首先查看优先级为31的线程,并以循环的方式进行调度.如果有优先级为31的线程可供调度,那么系统就会将CPU ...

  4. SYSBIOS学习笔记---线程(Threads)

    在SYS/BIOS中,广义上指被处理器执行的任何独立的指令流.线程是一个能够调用一个函数或者中断服务程序的单点控制.在sysbios系统中一共有硬件中断(HWI).软件中断(SWI).任务(Task) ...

  5. JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?

    前言:休整一个多月之后,终于开始投简历了.这段时间休息了一阵子,又病了几天,真正用来复习准备的时间其实并不多.说实话,心里不是非常有底气. 这可能是学生时代遗留的思维惯性--总想着做好万全准备才去做事 ...

  6. Java学习笔记——线程

    线程: 定义:线程是程序内的一个单一的顺序控制流程,也被称为“轻型进程(lightweight process)” 或“执行上下文(execution context )” 线程用于分隔任务 线程类似 ...

  7. Java学习笔记 线程池使用及详解

    有点笨,参考了好几篇大佬们写的文章才整理出来的笔记.... 字面意思上解释,线程池就是装有线程的池,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程 ...

  8. windows 并发与同步 学习笔记

    测试 5.2 windows 中断与异常 1.外部硬件中断是通过处理器上的中断引脚管或者本地APIC的内置模块来发生的:对于一个处理器,一旦被中单, 某个预先被设定的中断服务例程就被执行! 2.处理器 ...

  9. windows内核对象管理学习笔记

    目前正在阅读毛老师的<windows内核情景分析>一书对象管理章节,作此笔记. Win内核中是使用对象概念来描述管理内核中使用到的数据结构.此对象(Object)均是由对象头(Object ...

随机推荐

  1. iOS9 适配(杂七杂八)

    1.iOS9 以后,table cell 在旋转的时候会自动调整视图内容的布局,设置以下的属性,课禁止该行为. if (runTimeOSVersion >= 9.0f) { _listTabl ...

  2. Mac mySql ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)的解决办法

    我的环境:Mac 10.11.6 ,mysql  5.7.14  . mac mySql 报错ERROR 2002 (HY000): Can't connect to local MySQL serv ...

  3. swift:谈谈swift几种常见属性的区别

    一.前奏 Swift作为一门新语言,经过几年的发展,逐渐趋于完善,目前已经更新到3.0版本,它汇集许多其他语言的特点,例如JS.Paython.C++等,完全区别于OC.个人感觉它没有完全的OOP和O ...

  4. python中使用正则表达式

    正则表达式元字符:. ^ $ * + ? {} [] \ | ()第一部分:1.[] 常用来指定一个字符集,用于匹配其中的一个字符:^,$元字符在里面不起作用,但是+-*等符号在[]中还是有特殊含义的 ...

  5. python爬虫感想

    老师说,能用程序解决一个实际问题,说明已经会使用工具了.今天用python做了一个小爬虫,很幸运,成功了. 有几个难点:就是学会伪装,还有一个觉得打开的方式太多,有点糊涂,正则表达式也要加强了.

  6. Eclipse开发快捷键技巧

    1.alt+?或alt+/:自动补全代码或者提示代码 这个是我最得意的快捷键组合了,尤其是当输入syso几个字符之后,2个手指轻松按下这2个键的时候,自动就补全System.out.println() ...

  7. [转]Linux/Ubuntu sudo不用输入密码的方法

      通常我们并不以root身份登录,但是当我们执行某些命令 (command)时需要用到root权限,我们通常都是用"sudo command"来执行command.由于使用Ubu ...

  8. python中遍历文件的3个方法

    转自: http://www.jb51.net/article/54640.htm 用python进行文件遍历有多种方法,这里列举并说明一下. os.path.walk() 这是一个传统的用法. wa ...

  9. 前端 时间个性化 插件 jquery.timeago.js

    关键词 : 时间格式化 刚刚 N分钟前 N小时前 N天前 N月前 N年前 MM-dd hh:mm  或者  yyyy-MM-dd 前端: <span class="time" ...

  10. 相机拍的图,电脑上画的图,word里的文字,电脑屏幕,手机屏幕,相机屏幕显示大小一切的一切都搞明白了!

    相机拍的图,电脑上画的图,word里的文字,电脑屏幕,手机屏幕,相机屏幕显示大小一切的一切都搞明白了! 先说图片X×dpi=点数dotX是图片实际尺寸,简单点,我们只算图片的高吧,比如说拍了张图片14 ...