Linux kernel 如何同步内核工作队列线程?

Linux kernel 如何同步内核工作队列线程?,linux-kernel,kernel,linux-device-driver,Linux Kernel,Kernel,Linux Device Driver,我对Linux设备驱动程序和内核相当陌生。我基本上希望将一个workque线程(我们称它为a())与另一个函数(我们称它为B())同步。我的目的是在A运行时使B失败 目前,我所做的工作如下 A(){ active = true; // a variable shared b/w both A and B ... ... ... active = false; } B(){ if(active){ return -EBUSY } } 这是同步这两

我对Linux设备驱动程序和内核相当陌生。我基本上希望将一个workque线程(我们称它为a())与另一个函数(我们称它为B())同步。我的目的是在A运行时使B失败

目前,我所做的工作如下

A(){
  active = true; // a variable shared b/w both A and B
  ...
  ...
  ...
  active = false;
}

B(){
   if(active){
      return -EBUSY
    }
 }

这是同步这两个功能的正确方法吗?我还应该遵循其他策略吗?

对于Linux内核,这是一段糟糕的代码。尝试阅读有关互斥和信号量的内容


为什么要这样做

A
mmc\u rescan()
定义为
INIT\u DELAYED\u WORK(&host->detect,mmc\u rescan)

B:mmc\u suspend\u host()中的第一行代码是
cancel\u delayed\u work(&host->detect)

因此,您的A将在B中取消。这样做是有原因的,是由带来的

那么,用另一个同步来代替这个取消的原因是什么呢?如果您的内核中没有这个提交,只需拉它(),它可能会修复您的问题

更新 请参阅下一次提交,它们会更改MMC挂起行为:


  • 也许你只需要回接这些补丁来解决你的问题。或者至少它们会使修复变得更简单。

    您应该定义一个互斥体,并在代码中共享变量时使用它,这里是Linux内核中互斥体和条件函数的一个实现

    这取决于调用
    B()
    的位置(在哪个上下文、进程或原子中)以及每个函数有多少代码。请与我们共享实际代码。确切地说,是使用workqueue(进程上下文)运行的mmc_recan。B是mmc_suspend_主机。基本上,我需要避免在A运行时发生B!您到底有什么问题?您确定不希望B等待可用性吗?这是更常见的内核方法,除非用户模式的应用程序说它不想阻止。B已经有了阻止的机制。但是块是无限活跃的,我看到的唯一出路是从B返回。我确实有这些变化。我甚至注意到B中有取消。问题是mmc_重新扫描花费的时间太长,而B因此在mmc_刷新_计划的工作中被阻塞。现在,在这个阶段出现了一个请求mmc主机的客户机(但无法找到,因为mmc正在进行暂停活动)。我能想到的唯一方法是在mmc_重新扫描时避免挂起。您是否检查了源中是否发生了更改?对我来说,这听起来像个讨厌的虫子。我建议你在邮件列表中问这个问题(没有提到A和B,只是真实的函数名和实际问题的详细描述)。我在我的答案中添加了更新,请检查这些是否有帮助。是的,这基本上是Michael答案的重复。问题不在于共享变量,而在于同步。无论如何,问题似乎比这更复杂,仅仅在两个函数中锁定一些互斥锁可能不是最好的解决方案。这样B将只等待A完成。阅读评论以了解整体情况。对不起,我犯了错误,我没有像你说的那样了解整体情况。
    mutex
    只会迫使B等待A。在这种情况下,它甚至可能导致死锁。不是这么简单的。如有疑问,请阅读评论。