2009-07-22 77 views
32

在多任务系统中,一些异常情况会阻止执行进程或线程的进度。我将把进程和线程简单地称为“进程”。其中两个条件称为死锁和活锁。什么是饥饿?

前者指的是互相阻塞的进程,因此阻止执行。后者是指阻止彼此进展的过程,但并不实际阻止执行。例如,他们可能会不断导致对方回滚交易,而且无法完成交易。

另一种情况称为资源匮乏,其中进程进程所需的一个或多个有限资源已被其耗尽,并且除非进程进展,否则无法恢复。这也是活锁的特例。

我想知道是否有任何其他定义,特别是学术定义,因为“饥饿”不限于“资源匮乏”。特别欢迎参考。

而且,不,这不是家庭作业。 :-)

+4

虽然你在这个问题上,你也应该检查锁定车队,他们是非常有趣的。和讨厌。 http://en.wikipedia.org/wiki/Lock_convoy – 2009-07-22 23:45:44

+0

即使它是作业,这将是我见过的最好的家庭作业问题。 – 2017-12-14 23:12:31

回答

26

我不会说资源匮乏是一个活锁的特例。通常:

  • 在活锁中,没有线程取得进展,但它们仍在执行。 (在死锁状态下,它们甚至不会继续执行)

  • 当饥饿时,某些线程进行中并且某些线程未执行。

一个很好的解释:http://docs.oracle.com/javase/tutorial/essential/concurrency/starvelive.html。但我明白术语的选择可能会有所不同。

当谈到饥饿,我听到的定义是:

假设它是可以指定执行(隔行扫描)的无限路径与假设一致(旗语语义,OS调度器的行为...),使得线程T暂停等待一些资源,并且不会恢复,即使可能无限多次。然后T被称为挨饿。

但是,这种做法不符。假设两个线程在无限循环中执行关键部分。您的同步代码允许第一个线程每小时进入一次关键部分。它饿吗?这两个线程都允许进行,但第一个线程正在慢慢地完成它的工作。

最简单的饥饿来源是弱信号量。如果您使用的行为相似的同步原语(或构建您自己的),则会导致饥饿。

经典问题在那里饥饿是众所周知的:

有关详细信息,我衷心推荐信号灯的小书(免费):http://www.greenteapress.com/semaphores/

你在问是否每个饥饿都是由于等待一些资源而引起的。我会说 - 是的。

一个线程可以被挂起:

(1)上的一些阻塞系统调用 - 等待/获取互斥,旗语,条件变量; write(),poll()等。

(2)关于某些非阻塞操作 - 就像执行计算。

(1)上的饥饿在资源(互斥,缓冲等)上挨饿。 (2)上的挨饿在CPU上挨饿 - 你可以把它当作资源。如果发生,问题在于调度程序。

HTH

1

工作也是一种资源。当生产者 - 消费者设置中的工作分配不公平(或理想)时,某些线程可能无法获得足够的工作项目来保证它们始终处于忙碌状态。

38

想象一下,您正排队在餐厅购买食物,孕妇优先考虑。还有一大批孕妇一直到来。

你很快就会挨饿。 ;)

现在想象你是一个低优先级的过程,孕妇是高优先级的过程。 =)

+0

可笑但最好的解释 – user8027365 2018-02-09 18:32:03

12

在讨论优先级调度算法时,通常会出现饥饿或“不确定阻塞”的另一个领域。优先级调度算法有可能使一些低优先级进程无限期地等待。稳定的高优先级进程可以防止低优先级进程的运行。

在优先级调度程序的情况下,解决方案是“老化”。老化是逐渐增加在系统中等待很长时间的进程的优先级的技术。

6

饥饿就是当一个进程或服务没有被服务时,即使系统没有死锁。

这是我刚刚为澄清目的而编写的一个示例。

想象一下控制计算机访问WAN或类似的算法。这个算法可能有一个策略,说“提供优先访问那些将使用较少带宽的计算机”,这看起来像是一个合适的策略,但是当单台计算机想要访问网络以获取ftp上传时会发生什么情况在某处发送几个GB。仅凭这一政策,该计算机就会挨饿,因为该算法永远不会选择该计算机,因为总会有其他计算机请求较小的带宽使用量。

这就是所谓的饥饿。

1

举一个例子,在java中锁定饥饿。这是关于线程优先级的。不知道这个例子是否好,但你可以看看here

0

进程无法获得更长时间的资源或资源。这不是一个僵局,因为一个进程没有问题。 老化可以用来解决这个问题,老化因素用于每个请求。