linux-kernel – 重新安排内核delayed_work时会发生什么

前端之家收集整理的这篇文章主要介绍了linux-kernel – 重新安排内核delayed_work时会发生什么前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用内核共享工作队列,我有一个delayed_work结构,我想重新安排立即运行.

以下代码是否保证delayed_work将尽快运行?

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

在工作已经开始的情况下会发生什么? cancel_delayed_work将返回0,但如果工作当前正在运行或未安排,我不确定schedule_delayed_work将执行的操作.

解决方法

那么,你知道他们所说的必要性是所有发明的母亲(或在这种情况下的研究).我真的需要这个答案,并通过挖掘kernel / workqueue.c得到它.尽管答案主要包含在 doc commentsDocumentation/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_work或work_struct对象,并且您没有更改work->函数指针.

答案很长

首先,struct delayed_work通过嵌入struct work_struct作为其第一个成员,使用伪继承从struct work_struct派生.这个子系统使用一些惊人的原子位frigging来获得一些严重的并发性.当work_struct的数据字段设置为WORK_STRUCT_PENDING时,它“拥有”.当一个worker执行你的工作时,它是releases ownership并通过私有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-gt; func指针检查的原因是允许重用work_struct对象.)

但是请注意,如果工作仍然排队,那么简单地调用schedule_delayed_work()而不首先取消它将导致没有变化,因此您必须首先取消它.

编辑:哦,是的,如果您对Documentation / workqueue.txt中关于WQ_NON_REENTRANT的讨论感到困惑,请忽略它.不推荐使用此标志并将其忽略,并且所有工作队列现在都是非重新标记的.

猜你在找的Linux相关文章