代码之家  ›  专栏  ›  技术社区  ›  Daniel C. Sobral

什么是饥饿?

  •  38
  • Daniel C. Sobral  · 技术社区  · 15 年前

    在多任务系统中,一些异常情况会阻止进程或线程的执行。我将把进程和线程简单地称为“进程”。其中两种情况称为死锁和活锁。

    前者指的是相互阻塞的进程,从而阻止了其中一个进程的执行。后者是指阻止彼此进行的进程,但实际上并不阻止执行。例如,它们可能会不断地导致彼此回滚事务,而这两个事务都无法完成。

    另一种情况被称为资源匮乏,在这种情况下,进程进行所需的一个或多个有限资源已被它们耗尽,除非进程进展,否则无法恢复。这也是活锁的特殊情况。

    我想知道对于“饥饿”是否还有其他的定义,特别是学术上的定义,不限于“资源匮乏”。特别欢迎推荐信。

    不,这不是家庭作业。-)

    6 回复  |  直到 15 年前
        1
  •  30
  •   sdcvvc    11 年前

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

    • 在LiveLock中,没有线程取得进展,但它们会继续执行。(在僵局中,他们甚至不继续执行)

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

    说到饥饿,我听到的定义是:

    假设可以指定一个与假设(信号量语义、操作系统调度器行为…)一致的无限执行路径(隔行扫描),这样线程T就可以挂起等待某些资源,并且永远不会恢复,即使它可能无限多次。然后t被称为饥饿。

    但实际情况与此不符。假设两个线程在无限循环中执行关键部分。您的同步代码允许第一个线程每小时进入关键部分一次。是饥饿吗?两个线程都可以进行,但第一个线程的工作非常缓慢。

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

    饥饿众所周知的经典问题:

    更详细的内容,我全心全意推荐这本小册子(免费): http://www.greenteapress.com/semaphores/ .

    你在问,是否每一次饥饿都是由于等待某种资源造成的。我会说,是的。

    线程可以挂起:

    (1)在某些阻塞系统调用上-等待/获取互斥、信号量、条件变量;write()、poll()等。

    (2)在一些非阻塞操作上-例如执行计算。

    在(1)上的饥饿是在资源(互斥锁、缓冲区等)上的饥饿。

    在(2)上的饥饿是在CPU上的饥饿-您可以将它视为一种资源。如果发生这种情况,问题就出在调度程序上。

    高温高压

        2
  •  50
  •   NH.    7 年前

    想象一下,你在一家餐馆排队购买食物,孕妇优先购买。只有一大群孕妇一直来。

    你很快就会饿的。;)

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

        3
  •  12
  •   Umair    15 年前

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

    对于优先级调度程序,解决方案是“老化”。老化是一种逐渐提高在系统中等待很长时间的进程优先级的技术。

        4
  •  6
  •   Freddy    15 年前

    饥饿仅仅是当一个进程或服务没有被服务时,甚至当系统上没有死锁时。

    这是我只是为了澄清的目的而编的一个例子。

    设想一种控制计算机访问广域网或类似的算法。这个算法可以有一个策略,它说“为那些使用较少带宽的计算机提供优先访问权”。这看起来是一个合适的策略,但是当一台计算机想要访问网络以进行FTP上载,而该上载将在某个地方发送几个GB时会发生什么。单凭这个策略,那台计算机就会挨饿,因为算法永远不会选择那台计算机,因为总会有其他计算机要求更小的带宽使用。

    这就是所谓的饥饿。

        5
  •  1
  •   Christian Klauser    15 年前

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

        6
  •  0
  •   Sachith Muhandiram    9 年前

    一个进程在较长时间内无法获取资源。这不是死锁,因为一个进程运行时没有问题。 老化可以用来解决这个问题,每个请求都使用老化因子。