我正在使用内核共享工作队列,我有一个delayed_work结构,我想重新安排立即运行.
以下代码是否会保证delayed_work将尽快运行?
cancel_delayed_work(work);
schedule_delayed_work(work, 0);
Run Code Online (Sandbox Code Playgroud)
在工作已经开始的情况下会发生什么?cancel_delayed_work将返回0,但我不确定schedule_delayed_work如果工作当前正在运行或未安排将会怎么做.
嗯,你知道他们所说的必要性是所有发明的母亲(或在这种情况下的研究).我真的需要这个答案,并通过挖掘kernel/workqueue.c得到它.虽然答案大多包含在文档注释与结合Documentation/workqueue.txt,它不是明确规定不读的并发管理工作队列(cmwq)子系统的整体规范,即使是这样,一些信息是过时了!
简答
[您的代码]会保证delayed_work会尽快运行吗?
是的(以下警告)
在工作已经开始的情况下会发生什么?
它将在当前运行的函数退出后的某个时刻运行,delayed_work并在与最后一个CPU相同的CPU上运行,尽管已经在该工作队列中排队的任何其他工作(或者应该延迟的工作)将首先运行.这是假设你没有重新初始化您delayed_work或work_struct对象和你没有改变work->func重刑指针.
答案很长
首先,通过嵌入a 作为其第一个成员struct delayed_work来使用伪继承来派生.该子系统使用一些惊人的原子位frigging来实现一些严重的并发性.当它的字段设置了位时,A 是"拥有的" .当一个worker执行你的工作时,它会释放所有权并通过私有set_work_pool_and_clear_pending()函数记录最后一个工作池- 这是API最后一次修改对象(当然,直到你重新安排它).通话完全相同.struct work_structstruct work_structwork_structdataWORK_STRUCT_PENDINGwork_structcancel_delayed_work()
因此,如果您cancel_delayed_work()在工作函数已经开始执行时调用,它将返回false(如所宣传的),因为它不再由任何人拥有,即使它可能仍在运行.但是,当您尝试重新添加它时schedule_delayed_work(),它将检查工作以发现最后一个pool_workqueue,然后查明是否有任何pool_workqueue工作人员正在运行您的工作.如果它们(并且您没有更改work->func指针),它只是将工作附加到队列中,pool_workqueue这就是它如何避免重新入侵!否则,它会将它排队到当前CPU的池中.(work->func指针检查的原因是允许重用work_struct对象.)
但是请注意,如果工作仍然排队,只是在schedule_delayed_work()不取消它的情况下直接调用将导致没有变化,因此您必须首先取消它.
编辑:哦,是的,如果你对讨论的Documentation/workqueue.txt内容感到困惑WQ_NON_REENTRANT,请忽略它.不推荐使用此标志并将其忽略,并且所有工作队列现在都是非重新标记的.
| 归档时间: |
|
| 查看次数: |
3385 次 |
| 最近记录: |