www.5219.com

你的位置:www.5219.com > www.5219.com >

linux历程的休眠(期待行列步队)
日期:2019-08-02  来源:未知  

  当一个历程挪用 wake_up 正在期待队列上,所有的正在这个队列上期待的历程被置为可运转的。 这正在很多环境下是准确的做法。但有时,可能只要一个被的历程将成功获得需要的资本,而其余的将再次休眠。这时若是期待队列中的历程数目大,这可能严沉降低系统机能。为此,内核开辟者添加了一个“独有期待”选项。它取一个一般的睡眠有 2 个主要的分歧:

  一个被的历程可能抢占当前历程, 而且正在 wake_up 前往之前被安排四处理器。 可是, 若是你需要不要被安排出处置器时,能够利用 wake_up_interruptible 的同步变体. 这个函数最常用正在挪用者起首要完成剩下的少量工做,且不单愿被安排出处置器时。

  wake_up 队列中的每个非独有期待历程和一个独有期待历程。wake_up_interruptible 同样, 除了它跳过处于不成中缀休眠的历程。它们正在前往之前, 使一个或多个历程被、被安排(若是它们被从一个原子上下文挪用, 这就不会发生).

  这种 wake_up 所有的历程, 不管它们能否进行独有期待(可中缀的类型仍然跳过正在做不成中缀期待的历程)

  这些函数雷同 wake_up, 除了它们可以或许多达 nr 个独有期待者, 而不只是一个. 留意传送 0 被注释为请求所有的互斥期待者都被

  完成使命的代码还必需可以或许找到我们的历程,如许才能休眠的历程。需要一个称为期待队列的数据布局。期待队列就是一个历程链表,此中包含了期待某个特定事务的所有历程。

  (1)当期待队列入口设置了 WQ_FLAG_EXCLUSEVE 标记,它被添加到期待队列的尾部;不然,添加到头部。

  (2)当 wake_up 被正在一个期待队列上挪用, 它正在第一个有 WQ_FLAG_EXCLUSIVE 标记的历程后遏制.但内核仍然每次所有的非独有期待。

  (3)最初一步是放弃处置器。 但必需先查抄进入休眠的前提。若是不做查抄会引入竞态: 若是正在忙于的这个过程时有其他的线程方才试图你,你可能错过且长时间休眠。因而典型的代码下

  若是代码只是从 schedule 前往,则历程处于TASK_RUNNING 形态。 若是不需睡眠而跳过对 schedule 的挪用,必需将使命形态沉置为 TASK_RUNNING,还需要从期待队列中去除这个历程,不然它可能被多次。

  很少会需要挪用wake_up_interruptible 之外的函数,但为完整起见,这里是整个调集: