转自: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. 自定义NSLog

    我们在调试程序的时候,往往需要输出一些日志信息,用到NSLog函数,当我们准备发布程序,需要注释掉NSLog代码,这个时候往往会定义一个宏,在调试的时候,会输出日志,在Release正式版本的时候,会 ...

  2. hive 搭建

    Hive hive是简历再hadoop上的数据库仓库基础架构,它提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储,查询和分析存储再hadoop种的大规模数据机制,hive定 ...

  3. CentOS6.6安装virtualbox4.1.44

    本人用的是centos6.6,安装了virtualbox 4.1.44,启动后一直如上图报错,哪位前辈如果解决过这样的问题,麻烦指点指点,小弟在此先谢过了.

  4. IIS下Asp.Net应用程序多进程设置及Session共享

    背景: 目前项目中在单个进程的应用程序经常会遇到w3c.exe崩溃的情况,于是就设想是否可以通过IIS多进程的方案来避免出现该问题. 于是搜了下“怎么实现多进程的方案”,找到了这篇文章:http:// ...

  5. Easy Tag Write(3.1)

    package skyseraph.android.util; import skyseraph.easytagwrite.R; import android.app.Dialog; import a ...

  6. Select Tree Node

    这里用到了Oracle的一个树形结构查询函数select *  from record START WITH A.TREE_NODE IN ('COST_CTR_10053')CONNECT BY P ...

  7. jqGrid APi 详解

    jqGrid APi 详解 jqGrid皮肤 从3.5版本开始,jqGrid完全支持jquery UI的theme.我们可以从http://jqueryui.com/themeroller/下载我们所 ...

  8. JS的window.onload与JQuery的$(document).ready(function(){})的区别

    前段时间去面试被问及JS的加载(onload)与jQuery中加载(ready)方法的区别,瞬时懵逼了,关于这个知识点平时还真没怎么注意. 最近先来无事便查了一下资料, onload 事件(W3c上给 ...

  9. 【笔记】js parentsNode,lastChild,appendChild,insertBefore,nextSibling的意义及运用

    这几天看书看到这几个属性做几个笔记 parentNode:顾名思义,就是获取某元素的父元素等同于jq的parent(). *注意一下,在调用parentNode 方法的时候 调用的对象必须是用ID 或 ...

  10. 很好用的request转换为实体方法还有判断实体所有参数不能为空的方法

    /// <summary> /// 模型辅助处理类 /// 2016-04-18 /// </summary> public class ModelHelper { /// & ...