调度算法:Sleep并不总是如你预想的那样起作用

开发 前端
我们需要了解 CPU 时间片在各个线程上的调度原理,Sleep(0) 和 Sleep(1) 虽然只是参数上的不同,但底层运行逻辑却有很大的区别。

作为上一篇文章”即使运行高优先级线程,低优先线程也能运行”的另一个反面例子,人们会认为调用 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》

责任编辑:武晓燕 来源: 今日头条
相关推荐

2023-08-23 19:11:01

Kubernetes系统云原生

2020-06-27 17:33:42

云计算技术安全

2018-05-08 06:51:02

2014-07-16 09:53:57

分布式系统

2021-03-23 14:36:18

物联网智能交通IOT

2024-04-24 11:29:40

2021-07-26 09:16:34

智能家居安全物联网

2020-09-03 10:11:14

云计算远程工作

2022-06-07 14:55:23

苹果M2 芯片MacBook

2021-02-22 07:58:45

算法进程调度

2020-05-26 15:53:01

StraceDocker容器

2018-11-20 13:52:54

2017-09-26 11:06:15

数据库索引查询

2020-10-09 15:35:45

机器学习深度学习算法

2014-06-24 09:35:09

算法算法进化

2019-05-07 14:03:53

鼠标中键Windows 10Windows

2023-03-20 09:42:06

2023-11-22 13:18:02

Linux调度

2021-03-25 16:01:11

编程语言CPU机器语言

2021-03-26 06:00:37

编程语言CPU
点赞
收藏

51CTO技术栈公众号