(资料图片)
作为上一篇文章”即使运行高优先级线程,低优先线程也能运行”的另一个反面例子,人们会认为调用 Sleep(0) 是一种放弃 CPU 时间片的简单方法。举个例子,如果消费者线程目前没有数据可以处理,则可以调用此函数来出让 CPU 时间片,以等待生产者线程产生需要的数据。
让我们回想一下,调度程序会查找优先级最高的可运行线程,如果存在平局,则所有候选项大致平均共享 CPU。线程可以调用 Sleep(0) 来放弃其时间片,从而减少其在 CPU 中的份额。但请注意,这并不能保证其他线程将运行。
如果存在具有最高优先级的唯一可运行线程,它可以调用 Sleep(0),并保持很长一段时间,但它不会放弃 CPU。这是因为 Sleep 的时间为零会释放分配给它的时间片,但使线程可运行。由于它是唯一具有最高优先级的可运行线程,因此它会立即恢复 CPU。如果没有其他人排队,你实际上并没有将时间片出让给其他线程。
因此,如果使用 Sleep(0) 作为不那么有效的出让 CPU 的方法,它永远不会允许运行优先级较低的线程。这意味着各种后台活动(如索引)永远不会有机会运行,因为你的程序占用了所有 CPU 时间。更重要的是,你的程序从未真正释放 CPU 的事实,意味着计算机永远不会进入低功耗状态。笔记本电脑会更快地耗尽电池电量并运行得更热,终端服务器将无休止地消耗 CPU 时间片。
最好的办法是等待正确的同步对象,以便线程进入睡眠状态,直到有工作要做。如果你由于某种原因不能这样做,至少 Sleep 一个非零的时间值。这样,在短暂的时刻,你的线程不可运行,而其他线程(包括优先级较低的线程) 有机会运行。(这也将在一定程度上降低功耗,尽管不如等待正确的同步对象那么多。)
总结我们需要了解 CPU 时间片在各个线程上的调度原理,Sleep(0) 和 Sleep(1) 虽然只是参数上的不同,但底层运行逻辑却有很大的区别。由于程序可能会运行在各种不同配置的系统上,简单的使用 Sleep 来进行线程同步,将产生预料不到的偏差,你绝对不希望这样。所以,正如原文作者指出的,多线程下的线程协调工作,还是使用内核同步对象比较好。
最后Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。本文来自:《Consequences of the scheduling algorithm: Sleeping doesn’t always help》
4月25日21:00,美国最新数据分析,美国2月FHFA房价指数月率前值0 20%,公布值0 5%。美国最新数据分析公布
联盟第一!历史第一!全联盟都被他骗了,季后赛得分王果然很无敌,兰德尔,湖人主场,勒布朗詹姆斯,孟菲斯灰熊
中证网讯(记者彭扬)中国人民银行4月25日发布2023年3月份金融市场运行情况。数据显示,3月份,银行间货币市
小伙伴们,你们好,今天小夏来聊聊一篇关于高锰钢耐磨部件修复焊材,关于高锰钢耐磨部件修复焊材简述的文章
民族要复兴乡村必振兴为深入宣传贯彻党的二十大精神落实中央一号文件精神响应在全党大兴调查研究工作方案部
X 关闭
X 关闭