【问题标题】:Interaction between semaphores and context switches信号量和上下文切换之间的交互
【发布时间】:2018-01-05 20:22:33
【问题描述】:
假设线程 S 调用 semaphore.signal(),而线程 W1、W2 正在等待该信号量。
我知道信号量语义不能保证三个线程的调度顺序。但是,为了了解性能影响,我想弄清楚典型实现的行为。
具体来说(对于常用的信号量实现):
-
W1 和 W2 获取 CPU 是否都会被唤醒,其中一个会立即发现它必须再次阻塞并重新进入睡眠状态?
李>
S 在从semaphore.signal() 调用返回之前会进入睡眠状态吗?或者它会在没有signal() 调用的情况下一直停留在 CPU 上吗?
【问题讨论】:
标签:
multithreading
operating-system
semaphore
scheduling
【解决方案1】:
您的问题未详细说明。
来自 W1、W2 的一个线程将由信号量信号设置就绪,称为“W”
之后会发生什么不清楚,因为您没有充分指定调度程序/调度程序配置和状态。
如果有可用的空闲内核,S 可能会继续运行,而 W 可能会被分派到备用内核。
如果没有可用的空闲内核,W 可能会抢占 S:W 被分派到正在运行 S 的内核,并且 S 准备就绪,等待内核运行。
如果没有可用的空闲内核,内核可能会抢占在另一个内核上运行的另一个线程,以支持 W。因此,S 和 W 都会运行。
具体来说:
W1 和 W2 是否都会唤醒 CPU,其中之一
立即发现它必须再次阻塞并因此返回
睡觉?
为什么任何操作系统都会这样做?这是一大堆额外的工作,没有任何收获。信号量接收到一个信号,因此一个线程出列并准备就绪。另一个保持阻塞并在信号量线程队列中等待另一个信号。无需“唤醒”。
S 在从 semaphore.signal() 返回之前会进入睡眠状态吗
称呼?或者它会一直停留在 CPU 上吗?
没有 signal() 调用?
信令线程 S 不需要离开运行状态。如果 OS 内核调度算法和状态可以在另一个内核上运行 W,则 S 可以继续运行。如果 S 被 W 抢占,则它不再运行,并且卡在内核就绪队列中,等待内核可用。 W 可能刚刚准备好,没有被分派,S 可以继续运行。