gpt4 book ai didi

linux-kernel - 重新安排内核延迟工作时会发生什么

转载 作者:行者123 更新时间:2023-12-04 11:54:49 24 4
gpt4 key购买 nike

我正在使用内核共享工作队列,并且我有一个 delayed_work我想重新安排立即运行的结构。

以下代码能否保证 delayed_work会尽快运行吗?

cancel_delayed_work(work);
schedule_delayed_work(work, 0);

在工作已经在运行的情况下会发生什么? cancel_delayed_work将返回 0 ,但我不确定 schedule_delayed_work如果工作当前正在运行或未计划,则将执行此操作。

最佳答案

好吧,您知道他们所说的必要性是所有发明(或本例中的研究)之母。我真的需要这个答案,并通过挖掘 kernel/workqueue.c 得到了它。虽然答案大多包含在 doc comments结合 Documentation/workqueue.txt ,如果不阅读并发管理工作队列 (cmwq) 子系统的整个规范,它并没有清楚地说明,即使那样,一些信息已经过时了!

简短回答

Will [your code] guarantee that the delayed_work will run as soon as possible?



是(有以下警告)

What happens in a situation where the work is already running?



它将在当前运行的 delayed_work 之后的某个时间点运行。函数退出并在与最后一个相同的 CPU 上,尽管任何其他已在该工作队列中排队的工作(或到期的延迟工作)将首先运行。这是假设您尚未重新初始化 delayed_workwork_struct对象并且您没有更改 work->func化指针。

长答案

所以首先, struct delayed_work 使用伪继承从 struct work_struct 派生通过嵌入 struct work_struct作为它的第一个成员。这个子系统使用了一些惊人的原子位触发来实现一些严重的并发性。一个 work_struct当它是 data 时是“拥有的”字段有 WORK_STRUCT_PENDING 位设置。当一个 worker 执行你的工作时,它 releases ownership并通过私有(private) set_work_pool_and_clear_pending() 记录最后一个工作池函数 -- 这是 API 最后一次修改 work_struct对象(当然,直到您重新安排它)。调用 cancel_delayed_work() 做同样的事情。

因此,如果您调用 cancel_delayed_work()当你的工作函数已经开始执行时,它返回 false (如宣传的那样)因为它不再为任何人所有,即使它可能仍在运行。但是,当您尝试使用 schedule_delayed_work() 重新添加它时,它将 examine the work发现最后 pool_workqueue然后找出是否有任何 pool_workqueue的工作人员目前正在运行您的工作。如果它们是(并且您没有更改 work->func 指针),它只是将工作附加到该 pool_workqueue 的队列中。这就是它避免重新进入的方式!否则,它将在当前 CPU 的池中排队。 ( work->func 指针检查的原因是允许重用 work_struct 对象。)

但是请注意,只需调用 schedule_delayed_work()如果工作仍在排队,则不先取消将不会导致任何更改,因此您必须先取消它。

编辑:哦,是的,如果您对 Documentation/workqueue.txt 中的讨论感到困惑关于 WQ_NON_REENTRANT , 忽略它。该标志已被弃用和忽略,所有工作队列现在都是不可重入的。

关于linux-kernel - 重新安排内核延迟工作时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14965513/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com