我想理解为什么如果我试着睡在一个关键部分,这是一个并发问题,即使我锁定了。
我可能正在睡觉,因为我说我在做I / O.
答案 0 :(得分:3)
问题基本上是在你睡觉的时候,你没有完成任何事情。通常,您希望在尽可能短的时间内“进入”关键部分。您在关键部分花费的时间越长,其他任何线程都必须等待输入它的时间越长。
I / O几乎肯定会在任何关键部分之外完成。例如,如果您正在读取某些数据,则需要读取数据,然后输入临界区并将数据添加到某个结构中,以便其他所有内容都能看到它(例如,添加一个指向该节点的节点)将数据转换为矢量),然后离开CS。
在CS中执行I / O本身几乎没有充分的理由 - 您通常只需要一个线程来执行I / O,并且有一个队列(或deque,或其他)来处理输入到该线程或从该线程输出。向队列中添加内容或从队列中读取内容受CS(或可能是信号量等)的保护,但很快就会发生 ,因此一个线程可以做到这一点,然后快速离开,以便其他线程也可以。
答案 1 :(得分:1)
在关键部分睡眠的另一个潜在问题是它大大增加了优先级倒置场景的可能性。这在实时系统(以及我期望的非实时系统)中尤其成问题,尽管我想象的可能不那么天真。尽管有各种策略,但不同的操作系统采用不同的方法,这最终会影响应用程序的行为。
如果您不熟悉它,请考虑以下示例。
想象一下三(3)个不同优先级的任务:tLow,tMed和tHigh。 tLow和tHigh需要不同的时间来访问相同的关键资源; tMed做了自己的事。
tLigh在tLow放弃资源之前无法运行。 t在tMed阻塞或结束之前不能运行。任务的优先级已被颠倒;虽然它具有最高优先级,但它位于执行链的底部。
希望这有帮助。
答案 2 :(得分:0)
在关键部分内部睡眠的并发问题(在锁定信号量或互斥锁后也称为代码段)是其他处理更可能也会阻塞,等待第一个进程释放临界区
阻止其他进程并不总是坏事。如果其他进程必须等待第一个进程完成,那就是它的方式。因此,您的问题的答案取决于:如果这是您的应用程序的设计,则可以阻止其他进程。
当您进行I / O时,应该阻止您的进程,直到I / O完成。因此它不应该睡觉。但这是另一个故事。