Operating system 为什么在关键部分中睡眠是并发问题?

Operating system 为什么在关键部分中睡眠是并发问题?,operating-system,Operating System,我想了解,为什么即使我使用了锁,但如果我尝试在关键部分睡眠,会出现并发问题 我可能在睡觉,因为我在做I/O。在关键部分(也被称为锁定信号量或互斥后的代码部分)内睡觉的并发性问题是,其他处理也更可能阻塞,等待第一个进程释放关键部分 阻止其他进程并不总是坏事。如果其他进程必须等待第一个进程完成,那么就是这样。因此,您的问题的答案是,这取决于:如果是应用程序的设计,那么可以阻止其他进程 在执行I/O时,应阻止进程,直到I/O完成。因此它不需要睡觉。但这是另一个故事。问题基本上是,当你睡觉时,你没有完成

我想了解,为什么即使我使用了锁,但如果我尝试在关键部分睡眠,会出现并发问题


我可能在睡觉,因为我在做I/O。

在关键部分(也被称为锁定信号量或互斥后的代码部分)内睡觉的并发性问题是,其他处理也更可能阻塞,等待第一个进程释放关键部分

阻止其他进程并不总是坏事。如果其他进程必须等待第一个进程完成,那么就是这样。因此,您的问题的答案是,这取决于:如果是应用程序的设计,那么可以阻止其他进程


在执行I/O时,应阻止进程,直到I/O完成。因此它不需要睡觉。但这是另一个故事。

问题基本上是,当你睡觉时,你没有完成任何事情。一般来说,您希望在尽可能短的时间内“处于”关键部分。您在关键部分花费的时间越长,其他线程等待进入该部分的时间就越长

通常,I/O应该在任何关键部分之外进行。例如,如果您正在读取一些数据,您可能希望读取数据,然后进入关键部分并将数据添加到某个结构中,以便其他所有人都可以看到它(例如,将带有指向该数据的指针的节点添加到向量中),然后离开CS


在CS中进行I/O本身几乎没有什么好的理由——通常只有一个线程进行I/O,并有一个队列(或deque,或其他什么)来处理该线程的输入或输出。向队列中添加或从队列中读取内容受到CS(或信号量等)的保护,但发生速度很快,因此一个线程可以完成它的任务,然后快速离开,这样其他线程也可以。另一个在关键时段睡眠的潜在问题是,它显著增加了优先级反转场景的概率。这在实时系统(以及我所期望的非实时系统,尽管我可能天真地认为不是这样)中尤其有问题。尽管有不同的策略,但不同的操作系统采用不同的方法,这将最终影响应用程序的行为

如果你不熟悉它,请考虑下面的例子。

想象三(3)项不同优先级的任务:tLow、tMed和大腿。tLow和THGH需要不同的时间来访问相同的关键资源;tMed做自己的事情

  • tLow正在运行,tMed和大腿目前被阻塞(但不在关键部分)
  • tLow出现并进入关键部分
  • 因为它是系统中优先级最高的任务,所以它会运行
  • 大腿然后尝试进入关键资源,但由于tLow在其中而阻塞
  • tMed解除阻塞,因为它现在是系统中优先级最高的任务,所以它会运行
  • 在tLow放弃资源之前无法运行。在tMed阻塞或结束之前,tLow无法运行。任务的优先级被颠倒了;虽然它的优先级最高,但它位于执行链的底部


    希望这能有所帮助。

    在危急关头,你为什么要睡觉?你在“等待”什么?如果只是为了保护单个IO对象,没有理由不为IO使用“关键部分”(互斥体的名称选择不当,因为它建议锁定代码而不是数据)。它将阻止的唯一线程是在有机会对其执行IO之前无法继续的其他线程。这就是内部
    文件
    锁定的工作方式…对于输入,我同意。然而,对于输出,我没有。对于输出,通常将数据存放在队列中,然后继续处理就足够了。这可以(通常是显著地)减少线程等待而不是处理的时间。我考虑的更多的是一个组合操作,比如读-修改-写周期和原子性要求。