• C#夯实基础之多线程三:线程的优先级


    一.为什么需要优先级--线程调度的问题

       在现实生活中,优先级是一个很常见的现象:在火车站,如果你是孕妇,你是可以走进站中的专门绿色通道的,可以提前上火车以免拥挤;火警119匪警110出警的时候,都是人命关天的大事,是可以优先使用道路的,行人和车辆一律避让;在银行,如果你是白金VIP,也会有专门的绿色通道供你使用.从社会公平层面的优先级,到商业活动中的优先级,大家每天都生活在这样的环境之中,而且是按照这套游戏规则行事。

          Windows是一个用户操作系统,在设计上遵循着稳定性为准则,也就是说他要与人类的思维方式保持一致,才能用得舒服,线程的优先级可以说就是这一原则下的产物.如果都让车辆在路上一直依次行驶,那么120到现场的时候,人都可能已经挂了;如果病毒一直抢占CPU,那杀毒软件也就没有什么卵用了。

      这里需要注意现实生活中优先级与Windows中优先级的不同之处,现实生活中,我们可以通过新增资源(如增加窗口)优先处理高级别的业务,也可以通过对共同资源的调度(如110出警)来处理优化优先级高的业务。Windows则是在借鉴这些思路的时候进行了自己的一些改造,如调度队列、动态优先级调整等。

    二.了解Windows的线程调度

           Windows进化到现在,已经是一个时分和抢占式操作系统,它不同于实时操作系统,它通过动态地调整线程等待队列,从而确定线程使用cpu时间片的顺序。优先级高的线程有更大的概率排在队列的前面,同时获得更多数量的时间片,而不是更长时间的时间片。

       线程如果被sleep掉、等待io时,会释放他所拥有的cpu,如果线程不是主动释放CPU,线程调度器会抢占该线程。如果优先级相同的多个线程等待使用CPU,则会使用一个循环调度规则来实现队列的先后顺序。

       前面我们说过优先级是动态调整的,优先级低的不可能一直都是在等待,随着时间的运转,低优先级线程的优先级会提升,这样线程才有可能在等待结束时获得CPU

       再次强调,线程优先级只是提高了线程被调用的概率,并不是定义CPU调用线程的顺序,具体的工作就交给操作系统内部了。

    三.C#中的线程优先级

           C#中为我们提供了5个线程优先级别,如下所示:

       

       线程默认的优先级为Normal,可以在线程的运行过程中修改线程的优先级,如下所示:

    1 static void Main(string[] args)
    2 {
    3     Thread th = new Thread(delegate() { Console.WriteLine("start a new thread"); });
    4     Console.WriteLine(th.Priority);
    5     th.Start();
    6     th.Priority = ThreadPriority.Lowest;
    7     Console.WriteLine(th.Priority);            
    8     Console.Read();
    9 }

          结果如下:

          

    四.优先级反转

           这里要用到锁的知识,对这块有疑问的可以先去大致了解下锁。

       假设一种情况,线程A是高优先级线程,线程B是低优先级线程,线程B等啊等,终于等到自己,然后它锁住了一个资源R,然后线程A接手,但是它要用到RR被锁,然后A只有等待B释放锁,然而B优先级低,它只有经过漫长的等待才能提高自己的优先级得到执行,而此时A仍然在等待B释放锁,从表而看线程A是有非常多的执行机会,但线程A并未执行任何代码,反而B一直在执行,那么线程A何时能够得到资源呢?不知道,原来的优先级设定也就失去了意义。这就是所谓的优先级反转。

           那么,如何避免这一问题呢?这里给出一些建议。

          1.锁的尺寸应该尽量小,就是使用小锁而非大锁,比如锁定字符串就是一个非常大的锁

          2.锁的代码应该尽量短,这样锁定的时间就会尽量少

          3.可以使用原子锁

       使用优先级继承:也就是,高优先级进程TH在等待低优先级的线程TL占用的竞争资源时,为了使TH能够尽快获得调度运行,由操作系统把TL的优先级提高到TH的优先级,从而让TLTH的优先级参与调度,尽快让TL执行并释放掉TH欲获得的竞争资源,然后TL的优先级调整到继承前的水平,此时TH可获得竞争资源而继承执行。优先级继承还可以存在传递性,也就是说TL还需要更低的低优先级线程TM的同步资源时,也会把TM的线程优先级拉高到TL,这要看各个操作系统的具体实现。

    五.结尾

          在做应用程序时,我们建议,尽量不去干预线程的优先级,把调度的顺序交给操作系统处理就好。

    六.参考

          《C#高级编程(第7版)》

         博客  http://blog.csdn.net/feixiaoxing/article/details/7061582

         博客  http://blog.csdn.net/thl789/article/details/617629

  • 相关阅读:
    PHP的垃圾回收机制
    python使用httpHandler处理请求案例
    使用python中urllib.request.Request()来构建ua
    Pillow《转载》
    python数据格式化之pprint
    使用Mechanize实现自动化表单处理
    beautifulSoup《转》
    Python3网络爬虫(四):使用User Agent和代理IP隐藏身份《转》
    python urllib和urllib3包使用
    使用Mechanize实现自动化表单处理
  • 原文地址:https://www.cnblogs.com/gudi/p/6237887.html
Copyright © 2020-2023  润新知