Ben*_*nny 5 scheduling multithreading
该问题涉及多线程应用程序的输出,其中每个线程仅在标准输出上打印其 ID(用户分配的编号)。这里所有线程具有相同的优先级并竞争 CPU 配额以在标准输出上打印。然而,运行相同的应用程序足够多的次数将导致不同的 ID 打印在屏幕上的顺序。这个顺序是由于操作系统调度程序是一个软件,因此是确定性的。尽管如此,它的行为似乎是不确定的,这让我回到最初的问题。
对于任何和所有操作系统上的线程,这是 100% 正常的。您的线程库的文档、您可能会找到的任何示例和教程等都可能会说明这一点,因为人们在学习线程的绳索时经常会感到困惑。
这意味着除非您做出相反的安排(通过锁、信号量等),否则不要期望线程以任何特定顺序执行。 不要紧,他们在做什么,或者你怎么觉得他们是基于他们在做什么“可能发生”,等等。 简单地说:没有想到他们这样,是不是他们是什么,或者他们是如何的意思要使用的。不要费心想出诸如“我处于单用户模式,我正在尝试像水一样静止系统,因为......而且......等等”无限等等,这是浪费时间,那里没什么好学的。水不可避免地不是静止的,液体就是这样。故事结局。继续享受。
执行线程,如您所说,在您已设置为几乎不做任何事情的系统上几乎不做任何事情将导致调度程序的负载较轻,但请注意,CPU 仍以全速运行,并且几乎什么都不做快速发生并不一定比任何其他情况更可预测。 调度程序不打算同步或可预测地排序线程和进程。 我真的真的真的真的希望我说这不会激发你编造一个更复杂和伪逻辑的实验,因为如前所述,那是浪费时间,继续前进。
您可以并且可能会同步它们,但请注意,这是一个微妙的技巧,首先需要您了解为什么它们不只是“自然而然地做”(线索:因为他们没有理由这样做,所以他们没有这样做)。
“是什么让确定性操作系统看起来是不确定的?”
也许流体动力学的类比并不那么愚蠢。流体似乎是混沌的——烟雾甚至看起来是有生命的——而且我相信在数学中流体动力学和混沌理论的研究确实是交叉的。然而,大多数人可能不会对此感到震惊(“太神奇了!什么会导致自然现象中的这种行为?也许这是上帝的证据!”......不)因为我们可以理解确定性规则(定律流体动力学)在一定尺度上看将产生只能粗略预测的结果(“好吧,水会从玻璃杯中溢出......”),因此实际上是混乱的或不确定的(桌子上飞溅的模式)。即使那只是“很小的火”或一杯水,我们也认识到其中涉及数万亿个粒子的运动。
如果您曾经忙于循环使用计数器只是为了看看您的计算机可以计算多快,您就会知道这是每秒数十亿次的数量级。请记住,即使是“空闲”系统,大多数“次要”系统事件仍然会比通过打印 ID 来衡量活动的线程要重要得多,如果这就是线程所做的全部. 用我们流畅的比喻,即使在我们看来“完全无风”的一天,烟雾仍然没有形成一个有序的柱子(但我们可以更清楚地看到它自己的运动是如何影响它的)。
调度程序应该确保所有进程以平衡的方式运行(重力将确保水会溢出),但是,而不是每次给每个进程恰好 1 纳秒(这可能会使您的实验更具可预测性)。这一切都很好,因为再一次,调度程序的作用不是同步任何东西,而是让一切以适当平衡的方式发生。这两个目标并不相同。当您真正进入同步时,您会意识到同步可以实现清晰的平衡,但它是以牺牲效率为代价的。
此外,Linux 调度程序使用红黑树来组织其队列,它不是简单地在FILO行中运行所有内容(我怀疑任何现代通用调度程序都会这样做)。这意味着更大的复杂性,因此,更明显的混乱行为。
我不想鼓励你坚持你的注视,但如果你让线程执行更重要的任务,一个实际上需要他们花一些时间来做的事情,并在其他情况下启动它们偏移几秒钟空闲系统,那么实际上您将看到完全确定性的结果。 请记住,这并不是真正有效的同步方式 ——当风起而水变得汹涌时,你会看到混乱开始;)
“您是否知道有任何研究这些事件对操作系统调度程序的影响?”
不,因为它没有什么真正神秘的东西,就像流体一样。调度程序实际上是完全确定的,只是在您考虑的意义上或规模上不是。如果您printk
在内核代码中放入一堆信息并了解调度程序的算法,您将不会发现任何不确定性的东西——一切都会按照预期的方式发生。