等待信号量的进程调度

时间:2012-01-05 19:06:35

标签: c++ operating-system kernel mutex semaphore

当信号量的计数为0时,总是说,请求信号量的进程被阻塞并添加到等待队列中。
当某个进程释放信号量并且计数从0-> 1增加时,激活阻塞进程。这可以是从被阻止的进程中随机挑选的任何进程。

现在我的问题是:
如果将它们添加到队列中,为什么不按FIFO顺序激活阻塞进程?我认为从队列中选择下一个进程很容易,而不是随机选择一个进程并将其授予信号量。如果这个随机逻辑背后有一些想法,请解释一下。另外,内核如何从队列中随机选择进程? 从队列中获取随机过程就队列数据结构而言是一件复杂的事情 标签:各种操作系统,因为每个操作系统都有一个内核,通常用 C ++ mutex 分享相似的概念

6 个答案:

答案 0 :(得分:2)

FIFO是系统中等待列表的最简单数据结构 这不支持优先事项,但这不是绝对的答案 除此以外。根据所选的调度算法,不同 线程可能有不同的绝对优先级,或某种 衰减优先级可能有效,在这种情况下,操作系统可能会选择 在某个前一个时间间隔内具有最少CPU时间的线程。 由于这种策略被广泛使用(特别是后者),所以 通常的规则是考虑你不知道(尽管有绝对的 优先级,它将是具有最高优先级的线程之一。)

答案 1 :(得分:1)

不是它不能是FIFO;事实上,我打赌很多实现都是因为你说的原因。规范并不是随机选择过程;它是未指定的,因此您的程序不应该依赖于以任何特定方式选择它。 (它可以随意选择;只是因为它不是最快的方法并不意味着它无法完成。)

答案 2 :(得分:1)

当一个进程“随机”安排时,并不是随机选择一个进程;这是选择过程不可预测的。

Windows内核使用的算法是等待信号量的线程队列(Windows调度“线程”,而不是“进程”)。释放信号量后,内核会调度队列中等待的下一个线程。但是,调度线程不会立即使该线程开始执行;它只是通过将线程放入等待运行的线程队列中来使线程能够执行。在CPU没有更高优先级的线程执行之前,线程实际上不会运行。

当线程在调度队列中等待时,实际执行的另一个线程可能在同一个信号量上等待。在传统的队列系统中,新线程必须停止执行并转到队列的末尾,等待该信号量。

但是,在最近的Windows内核中,新线程不必停止并等待该信号量。如果已分配该信号量的线程仍然位于运行队列中,则可以将信号量重新分配给旧线程,从而使旧线程再次返回等待信号量。

这样做的好处是,即将必须在队列中等待信号量然后在队列中等待运行的线程将不必等待。缺点是你无法预测哪个线程接下来会实际获得信号量,这是不公平的,因此等待信号量的线程可能会饿死。

答案 3 :(得分:1)

这里的所有其他答案都是对基本问题的精彩描述 - 尤其是围绕线程优先级和就绪队列。然而,另一件需要考虑的事情是IO。我这里只讨论Windows,因为它是我所知道的唯一具有任何权限的平台,但其他内核可能也有类似的问题。

在Windows上,当IO完成时,称为内核模式APC(异步过程调用)的内容将对启动IO的线程进行排队,以便完成它。如果线程正好在调度程序对象(例如示例中的信号量)上等待,则该线程将从该对象的等待队列中删除,这导致(内部内核模式)等待完成(类似于)STATUS_ALERTED。现在,由于这些内核模式的APC是一个实现细节,并且您无法从用户模式中看到它们,因此WaitForMultipleObjects的内核实现会在该点重新启动等待,这会导致您的线程被推送到队列的后面。从内核模式的角度来看,队列仍处于FIFO顺序,因为底层等待API的第一个调用者仍处于队列的头部,但是从您的角度来看,在用户模式下,您只是被推到了由于你没有看到的东西,很可能无法控制队列的后面。这使得队列顺序在用户模式下显示为随机。实现仍然是一个简单的FIFO,但由于IO,它看起来不像更高级别的抽象。

我在这里猜测更多,但我认为类似于unix的操作系统在信号传递和内核需要劫持进程以在其上下文中运行的地方有类似的限制。

现在这并不总是发生,但文档必须是保守的,除非明确保证订单是FIFO(如上所述 - 至少对于Windows - 它不可能)然后描述顺序在文档中作为“随机”或“未记录”或某事,因为随机过程控制它。它还为操作系统供应商提供了在稍后更改订单的优势。

答案 4 :(得分:0)

进程调度算法非常特定于系统功能和操作系统设计。很难对这个问题给出一个好的答案。如果我在普通PC上,我想要一些具有良好吞吐量和平均等待/响应时间的东西。如果我在一个系统上,我知道我所有工作的优先级,并且知道我绝对希望我的所有高优先级工作都先运行(并且不关心抢占/饥饿),那么我想要一个优先级算法。

就随机选择而言,动机可能有各种原因。一种是如上所述的良好吞吐量等的尝试。然而,这将是不确定的(假设的)并且不可能证明。这个属性可能是概率的利用(随机样本等),但同样,证据只能基于这是否真的有效的经验数据。

答案 5 :(得分:-1)