2010-11-11 29 views

回答

0

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

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

当你在做I/O时,你的进程应该被阻塞,直到I/O完成。因此它不需要睡觉。不过那是另一回事了。

2

问题是,当你在睡觉时,你没有完成任何事情。一般而言,您希望尽可能短时间地在关键部分“进入”。您在关键部分花费的时间越长,其他线程将不得不等待输入的时间越长。

作为一项规则,I/O几乎可以肯定在任何关键部分之外完成。举例来说,如果你正在读取一些数据,你会想要读取数据,然后进入关键部分并将数据添加到某个结构中,这样所有其他数据都可以看到它(例如,添加一个指向该结点的节点数据转化为矢量),然后离开CS。

在CS中执行I/O本身几乎没有什么好的理由 - 你通常只需要一个线程来完成I/O,并且有一个队列(或者deque或者其他)来处理与该线程的输入或输出。向队列添加或读取某些内容受CS(或信号量等)保护,但快速发生,因此一个线程可以完成其任务,然后快速退出,以便其他线程也可以完成。

+0

如果IO只是保护单个IO对象,那么没有理由不使用“关键部分”(互斥体的名称选择不当,因为它建议锁定代码而不是数据)。它会阻止的唯一线程是其他人无法继续,直到他们有机会对其执行IO。这是如何内部'文件锁定工程... – 2012-01-20 15:21:52

+0

对于输入,我同意。但是,对于输出而言,我不知道。对于输出,通常足够将数据存入队列,然后继续处理。这可以(通常大大减少)线程花费等待而不是处理的时间。 – 2012-01-20 15:31:08

+0

我在考虑更多的是像一个具有原子性要求的读 - 修改 - 写周期这样的组合操作。 – 2012-01-20 16:01:58

1

在临界区睡眠的另一个潜在问题是它会显着增加优先级反转方案的可能性。这在实时系统(以及我期望的非实时系统,尽管也许天真地我想象不那么重要)中可能是特别有问题的。尽管有不同的策略,但不同的操作系统会采用不同的方法,最终会影响应用程序的行为。

如果您不熟悉它,请考虑以下示例。想象三种不同优先级的任务:tLow,tMed和tHigh。 tLow和tHigh将需要不同的时间来访问相同的关键资源; tMed做它自己的事情。

  1. tLow正在运行,tMed和tHigh目前被阻止(但不在关键部分)。
  2. tLow进入临界区域。
  3. t高畅通,因为它是系统中最高优先级的任务,它运行。
  4. t然后尝试输入关键资源,但在tLow存在时进行阻止。
  5. tMed解锁并且因为它现在是系统中最高优先级的任务,所以它会运行。

tHigh在tLow放弃资源之前无法运行。直到tMed块或结束tLow才能运行。任务的优先顺序已经颠倒过来;尽管它具有最高的优先级,但仍处于执行链的底部。

希望这会有所帮助。

相关问题