25.9 Thread Scheduling and Priorities 线程调度和优先权

抢占式(preemptive)操作系统必须使用某种算法,来决定在什么时候调度哪些线程以及调度多长时间。本节将讨论Windows采用的算法。本章前面部分,我提到每个线程的内核对象都包含一个上下文结构。上下文结构反映了当线程上一次执行时,线程的CPU寄存器的状态。在一个时间片(time-slice)之后,Windows检查现有的所有线程内核对象。在这些对象中,只有那些没有正在等待什么的线程才适合调度。Windows选择一个可调度的线程内核对象,并上下文切换到它。Windows实际记录了每个线程被上下文切换到的次数。可以使用像Microsoft Spy++这样的工具查看这个数据。图25-5展示了一个线程的属性。注意,这个线程已被调度了103505次。

在这个时候,线程正在执行代码,并且在它的地址空间操作数据。过了另一个时间片后,windows 执行另一个上下文切换。Windows 从系统启动的时候就开始执行上下文切换,直到系统关闭的时候为止。

之所以windows 被叫做抢占式多线程操作系统,是因为任何时候线程可能停止并调度另一个线程。就像你接下来看到的那样,你有控制权,但不是全部的。记住,你不能保证你的线程永远运行。

Note:开发者经常会问我,如何才能保证线程在某些事件之后一段时间内开始运行——比如,如何确保某个线程在串口接收到数据的1ms 内开始运行。我的回答:你不能。

实时操作系统能做这样的保证,但windows 不是实时操作系统。实时操作系统需要对硬件(硬盘控制器、键盘以及其他组件的延迟时间)的运行情况有一个精确的把握。但是,Microsoft Windows 的设计目标是兼容大范围的硬件,包括不同的CPU、不同的驱动、不同的网络等等。简单地说,Windows 不是设计成实时操作系统。我还要补充一句:CLR使托管代码的行为变得更不“实时”了。这是有很多原因的,包括DLL的JIT加载,代码的JIT编译,以及GC介入的不确定性。

每个线程都被赋予了0(最低)到31(最高)级别的权限。当系统需要分配线程到CPU的时候,它会检查权限级别是31的线程,并以轮流(round-robin)的形式被调度。如果31 级优先权的线程是可调度的,那么它将被分配到CPU。在这个线程的“时间片”的最后,系统会检查是否还有其他级别为31 并且能运行的线程;如果是就被分配到CPU。

只要31优先级的线程是可调度的,那么就轮不到优先级为0到30 的线程被调度到CPU。这种条件叫做“饥饿starvation”,当较多较高权限的线程占用了CPU,导致较低权限的CPU无法执行,就会发生这种情况。在多处理器机器上饥饿发生的可能性要小的多,因为这种机器上优先级为31的线程和优先级为30的线程可以同时运行。系统总是保持每个CPU处于忙碌状态,只有没有线程可调度的时候,CPU才空闲下来。

较高优先级的线程总是抢占较低优先级的线程。例如,如果有一个优先级为5的线程在运行,同事又有一个更高优先级的线程准备要运行,系统会马上挂起较低权限的线程(及时它正运行到它时间片的一般)并且分配CPU给较高的线程,而且该线程获得“满时间片”。

当系统启动的时候,系统会创建一个叫做“0页线程 zero page thread”的特殊线程。这个线程是整个系统唯一获得0级优先权的线程。0 页线程负责在其他线程要执行的时候,将RAM中的自由页归零。

微软意识到,开发人员在为线程分派优先级的时候,很难做到完全合理。为此,windows公开了优先级系统的一个抽象层。

设计应用程序的时候,应该决定自己顶应用程序是需要比机器上同时运行的其他应用程序更大还是更小的响应能力。然后选择一个进程优先级类(priority class)来反映你的决定。Windows支持6个进程优先级类:Idle,Below Normal,Normal,Above Normal,High和Realtime 。因为Normal是默认优先级类,所以它是最常用的优先级类。

如果一个应用程序(比如屏幕保护程序)在系统什么事情都不做的时候运行,就适合分配Idle优先级类。注意,即使一台计算机没有被交互的使用,仍有可能处于忙的状态(比如作为一台文件服务器运行),它不应该和一个屏幕保护程序竞争CPU时间。一些执行统计学跟踪分析的应用程序需要定期更新与系统有关的状态,这种应用程序一般不应妨碍执行更关键的任务。

只有在非常重要的时候,你才能使用High priority类。如果可能,尽量避免使用real-time类。Realtime 的优先级非常高,它甚至可能敢要操作系统任务,比如阻碍一些必要的磁盘I/O和网络传输。除此之外,一个Realtime进程的线程可能造成不能及时的处理键盘和鼠标输入,用户户觉得自己的计算机“死机”了。简单的说,必须要有很好的理由才能使用Realtime优先级,比如需要响应延迟(latency)很短的硬件事件,或者要执行一些不能中断的非常“短命”的任务。

Note:为了保证系统能够流畅运行。进程使不能以Realtime的优先级来运行的,除非用户有“提高调度优先级(Increase Scheduling Priority)”特权,否则进程不能以Realtime 优先级类运行。任何用户只要是管理员或者Power User,就默认有这个特权。

一旦你选择了一个优先级类,不暂时不用考虑你的应用程序和其他应用程序的关系。只要把注意力放到你的应用程序的线程上。Windows 支持7种相对线程优先级(relative thread priority):Idle、Lowest、Below Normal、Normal、Above Normal、Highest 以及 Time-Critical。这些优先级是相对进程优先级的。同样的,默认的相对线程优先级是Normal。

总而言之,你的进程是一个优先级类的成员。在你的进程里,要为各个线程分配相对优先级。到目前为止,我一直没有提到关于0到31的线程优先级的事情。应用程序开发者永远不会直接处理这些优先级。相反,系统将进程的优先级类和其中的一个线程的相对优先级映射到一个优先级(0到31)。表25-1总结了进程的优先级类和线程的相对优先级的映射关系。

举个例子,Normal 进程中的一个Normal 线程的优先级是8.由于大多数进程都是Normal 优先级,大多数线程也是Normal 优先级,所以系统中的大多数线程的优先级都是8.

对于High 优先级进程中的一个Normal 线程,它的优先级是13.如果将进程的优先级类改成Idle,线程的优先级变成4。记住,线程的优先级是相对于进程优先级类的。如果更改以进程的优先级类,线程的相对优先级不会改变,但它的优先级值会改变。

请注意,表中线程优先级没有0。这是因为前面我们已经讲到的0 页线程,0优先级保留给0页线程了,系统不允许其他线程的优先级为0.而且一下优先级也是不能获得的:17,18,19,20,21,27,28,29 以及30。但是,如果是编写运行在内核模式的设备驱动程序,可以获得这些优先级;用户模式的应用程序是不能获得的。还要注意,Realtime 优先级的线程,其优先级不能低于16。同理,非Realtime 优先级小吃店优先级不能高于15。

Note:大家可能对“进程优先级类”这个概念比较疑惑。你可能会觉得这就意味着windows能调度进程。但是,windows是永远不会调度进程的;它调度的只有线程。“进程优先级类”是Microsoft 提出的一个抽象的概念,是为了帮助你理解自己的应用程序和其他正在运行的应用程序的关系,它没有别的用途。

Important:一般情况下,建议降低一个线程的优先级,而不是提高另一个线程的优先级。如果你要运行一个需要长时间的计算限制的任务(比如编译代码、检查拼写、重算电子表格等等),一般建议降低该线程的优先级。如果线程要快速下响应某个事件,然后运行非常短暂的时间,再回复为等待状态,则建议提高该线程的优先级。高优先级线程在其声明中的大多数时间里都处于等待状态,这样才不至于影响系统的总体响应能力。Windows 资源管理器(Windows Explorer)通过按键盘上的win 键来响应就是一个例子。当用户按下win 键,windows 资源管理器会抢占其他较低优先级的线程,并列出菜单。用户在菜单上选择的时候,windows 资源管理器的线程会快速响应每一次按键(或者是鼠标移动),更新菜单,并停止运行,知道用户继续在菜单中导航。

正常情况下,进程根据启动它的进程来分配到一个优先级(Normally, a process is assigned a priority class based on the process that starts it running)。大多数进程都是由windows 资源管理器启动的,它在Normal 优先级类中生成它的所有子进程。托管应用程序不应该表现为拥有它们自己的进程;相反,它们应该表现为在一个AppDomaiin 中运行。所以,托管应用程序不应该更改它们的进程的优先级类,因为这会影响进程中运行的所有代码。例如,许多ASP.NET 应用程序都在单个进程中运行,每个应用程序都在它自己的AppDomain 中。类似的还有Silverlight 应用程序,它在一个Internet 浏览器进程中运行。还有托管存储过程,它在Microsoft SQL Server 进程中运行。

另一方面,你的应用程序可以更改它的线程的相对线程优先级,这需要设置Thread 的Priority 属性,向它传递ThreadPriority 枚举类型中定义的5个值之一,即Lowest,BelowNormal,Normal,AboveNormal 或者Highest。然而,就像Windows 为自己保留了优先级0和Realtime 范围一样,CLR为自己保留了Idle和Time-Critical优先级。今天的CLR还没有以Idle优先级运行的线程,但这一点将来可能发生改变。然而,如第21章“自动内存管理(垃圾回收)”讨论的那样,CLR的终结器线程以Time-Critical 优先级运行。所以,作为托管应用程序的开发人员,你实际只需使用表25-1中5个加了底纹的相对线程优先级。

Important:如今,大多数应用程序都没有利用线程优先级。然而,在我设想的世界中,CPU 保持100%的使用率。在这种情况下,为了保证系统响应能力不受影响,线程优先级就显得至关重要。遗憾的是,多年来最终用户已养成了一个习惯:一旦看到太高的CPU 使用率,就甘距应用程序要失去控制了。在问的新世界中,需要对用户进行“知识普及”,让它们明白高的CPU使用率是一件好事情——表明计算机正在主动为用户处理有用的信息。如果所有CPU都忙于优先级8和以上的线程,就真的出问题了。这意味着应用程序在响应用户的输入时遇到麻烦。可能未来的“任务管理器”在报告CPU 使用情况时,会将线程优先级考虑在内;诊断有问题的系统时,这种信息是相当有帮助的。

应该指出的是,System.Diagnostics命名空间包含一个Process类和一个ProcessThread类。这两个类分别提供了进程和线程的Windows视图。如果要开发者用托管代码写工具(utility)应用程序,或者想建构代码来帮助自己对其进行调试,就可以使用这两个类。事实上,这正是为什么这两个类在System.Diagnostics命名空间中的原因。应用程序需要以特殊的安全权限运行才能使用这两个类。例如,在Silverlight应用程序或者ASP.NET应用程序中,就不能使用这两个类。

另一方面,应用程序可使用AppDomain和Thread类,它们公开了AppDomain和线程的CLR视图。大多数情况下,不需要特殊安全权限来使用这两个类,虽然某些操作仍需提升权限才可以。

转载于:https://www.cnblogs.com/TivonStone/archive/2010/09/12/1824518.html

CLR_via_C#.3rd 翻译[25.9 线程调度和优先权]相关推荐

  1. CLR_via_C#.3rd 翻译[1.5 本地代码生成工具NGen.exe]

    1.5 The Native Code Generator Tool: NGen.exe 本地代码生成工具NGen.exe NGen.exe是和.NET框架绑定在一起的.当用户的机器上安装了一个应用程 ...

  2. 《WCF技术内幕》翻译25:第2部分_第5章_消息:创建一个消息(下)之MessageFault

    Message和SOAP Fault老徐备注1 Message类型定义了一些用来创建表示SOAP Fault消息对象的工厂方法.SOAP Fault是SOAP消息的一种形式,它用来表示错误信息.在SO ...

  3. 这7个翻译神器超级猛!网页翻译、文档翻译,无所不能

    平时在工作.学习生活中,经常需要翻译文本文档,我们都会借助一些翻译软件.下面这7个翻译神器可真猛!干掉了很多翻译软件,好用又精准. 01.智能翻译官 这是一款多功能的翻译工具,包含文档翻译.文字翻译. ...

  4. 【论文翻译】Scene Text Detection and Recognition: The Deep Learning Era 场景文本检测和识别:深度学习时代

    原文地址:Scene Text Detection and Recognition: The Deep Learning Era 文章目录 摘要 1.引言 2.深度学习时代之前的方法 2.1概括 3. ...

  5. 高发疾病分布特征分析

    高发疾病分布特征分析 仅列举三种高发疾病,对其患病者年龄分布.性别分布.危险因素等进行可视化以探究一些有趣的规律. 高发疾病分布特征分析 高发疾病分布特征分析 一.数据可视化 1.1 不同年龄病别总患 ...

  6. 【英语做题】英语“八股文“学习

    英语八股 做题顺序: 1 写作(<25分钟) 1.1 单词替换 1.2 万能句型 1.3 文章 1.3.1 谚语警句型 1.3.2 图画图表型 1.3.3 论说文 1.3.4 书信作文 2 听力 ...

  7. 浙江大学计算机博士很难复试专业课,浙江大学考博英语复试经验参考

    [导语]博士是标志一个人具备出原创成果的能力或学力的学位,是目前级别的学位.具备出原创成果的能力或学力是博士学位的核心内涵,也是拥有博士学位的人的最本质特征.无忧考网整理了浙江大学考博英语复试经验参考 ...

  8. 计算机应用基础 双语 答案,计算机应用基础(双语)课件PPTChax

    计算机应用基础(双语)课件PPTChax (55页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.90 积分 Chapter 1Computer Ha ...

  9. 英语四级 刘晓燕 550分计划

    英语四级 刘晓燕 550分计划 日落跌进迢迢星野,人间忽晚,山河已秋 月望探出银河璀璨,岁月漫长,万物生长 太阳跌落远远的地方,突然发现时光走得太快,而人间山河也已经变了模样,于是唏嘘不已,倍觉感伤 ...

最新文章

  1. java 判断非ascii字符_文件名中的JavaMail和非ASCII字符
  2. linux变量inode,linux字符cdev和Inode的关系
  3. 深入理解JVM虚拟机(七):虚拟机字节码执行引擎
  4. python 打包文件
  5. java 缓存分页_基于redis做缓存分页
  6. java GUI怎么输入_在Swing中创建Java GUI以进行表单输入
  7. (转载)芹菜拌豆腐皮 降压小凉菜
  8. 搜狗浏览器收藏夹在哪_搜狗浏览器居然流氓到操作我的微博账号
  9. 字符串lcfirst解析
  10. Django中的templates(你的HTML页面放哪里)
  11. 计算机第四次评估报告,建议置顶,天天那么多问计算机的。看看第四轮评估的结果。...
  12. cesium加载倾斜优化_干货 | 6款倾斜摄影裸眼3D采集软件推荐给大家
  13. 鱼塘钓鱼 (贪心+枚举)
  14. C# 谷歌邮箱发送邮件
  15. word转换成pdf后图片压缩失真的解决方法
  16. Python多张图片合并成一个PDF
  17. 英特尔Intel CPU睿频原理探讨
  18. Mac系统关闭体统提示升级
  19. 【024】Vue+Springboot+mysql员工考勤管理系统(多角色登录、请假、打卡)(含源码、数据库、运行教程、实验报告)
  20. C++:二维数组参数传递

热门文章

  1. kettle 数据提取效率提升
  2. js 去除空格回车换行
  3. 怎么对MySQL数据库操作大数据?这里有思路
  4. Enum枚举 简单的使用
  5. C++数据结构与算法(九) 树,优先级队列,最大堆的实现
  6. mysql将最大金额加1000_Mysql数据库笔记
  7. python中随机生成数字生成对了是猜对了_python入门(一) 一个猜随机数小游戏...
  8. Python接口自动化之logging日志
  9. 课节6: 图神经网络进阶模型之 ERNIESage下
  10. Kava将于下午2时重新启动Kava Chain