Linux kernel 等待队列与竞争条件

Linux kernel 等待队列与竞争条件,linux-kernel,Linux Kernel,我正在阅读Robert Love的“Linux内核开发”,并找到下面的代码以等待事件 定义等待(WAIT); 添加等待队列(q和等待); 而(!条件){ //如果条件发生更改,并在此处调用wake_up(),会发生什么情况? 准备等待(&q,&wait,任务可中断); if(信号_待定(当前)) /*手柄信号*/ 附表(); } 完成等待(&q,&wait); 我的问题和上面的代码一样。如果条件发生更改,并且在条件检查之后但在准备等待之前调用了wake\u up(),会发生什么情况? 我在这里

我正在阅读Robert Love的“Linux内核开发”,并找到下面的代码以等待事件

定义等待(WAIT);
添加等待队列(q和等待);
而(!条件){
//如果条件发生更改,并在此处调用wake_up(),会发生什么情况?
准备等待(&q,&wait,任务可中断);
if(信号_待定(当前))
/*手柄信号*/
附表();
}
完成等待(&q,&wait);
我的问题和上面的代码一样。如果条件发生更改,并且在条件检查之后但在准备等待之前调用了
wake\u up()
,会发生什么情况?
我在这里的解释(可能是错误的)是,因为
prepare\u to\u wait
使线程
TASK\u可中断
并调用
schedule()
在条件更改后,它将永远休眠(除非它收到信号或调用另一个
wake\u

是的,此代码实际上是已运行的代码,在
准备等待
调度
调用之间,应检查
条件
(如果满足则中断)

有趣的是,在以下描述中(第60页),本书提到了
fs/notify/inotify/inotify\u user.c
文件中函数
inotify\u read()
的实现:

DEFINE_WAIT(wait);
...
while (1) {
  prepare_to_wait(&group->notification_waitq,
    &wait,
    TASK_INTERRUPTIBLE);

  if (<condition>) // very simplified form of checks
    break;
  if (signal_pending(current))
    break;

  schedule();
}
finish_wait(&group->notification_waitq, &wait);
...
定义等待(WAIT);
...
而(1){
准备等待(&U)组->通知等待,
&等等,
任务(可中断);
if()//非常简化的检查形式
打破
if(信号_待定(当前))
打破
附表();
}
完成\u等待(&组->通知\u等待,&等待);
...
根据作者的说法,“遵循模式”:

此函数遵循示例中列出的模式。主要区别在于 它检查
while()
循环体中的条件,而不是
while()
声明本身。这是因为检查情况很复杂,需要抓取锁。循环通过
break
终止

但是,该代码显示另一种模式,它检查
准备到等待
调度
调用之间的条件。而该代码实际上是正确的(无种族)。 另外,该代码不使用
添加等待队列
,这在存在
准备等待
时是多余的


在同一作者的另一本书《Linux驱动程序开发》(3d修订版)中,等待队列的使用似乎更准确。例如,参见第6章,高级字符驱动程序操作。

是的,此代码实际上是赛车,在
准备等待
调度
调用之间,应检查
条件
(如果满足则中断)

有趣的是,在以下描述中(第60页),本书提到了
fs/notify/inotify/inotify\u user.c
文件中函数
inotify\u read()
的实现:

DEFINE_WAIT(wait);
...
while (1) {
  prepare_to_wait(&group->notification_waitq,
    &wait,
    TASK_INTERRUPTIBLE);

  if (<condition>) // very simplified form of checks
    break;
  if (signal_pending(current))
    break;

  schedule();
}
finish_wait(&group->notification_waitq, &wait);
...
定义等待(WAIT);
...
而(1){
准备等待(&U)组->通知等待,
&等等,
任务(可中断);
if()//非常简化的检查形式
打破
if(信号_待定(当前))
打破
附表();
}
完成\u等待(&组->通知\u等待,&等待);
...
根据作者的说法,“遵循模式”:

此函数遵循示例中列出的模式。主要区别在于 它检查
while()
循环体中的条件,而不是
while()
声明本身。这是因为检查情况很复杂,需要抓取锁。循环通过
break
终止

但是,该代码显示另一种模式,它检查
准备到等待
调度
调用之间的条件。而该代码实际上是正确的(无种族)。 另外,该代码不使用
添加等待队列
,这在存在
准备等待
时是多余的


在同一作者的另一本书《Linux驱动程序开发》(3d修订版)中,等待队列的使用似乎更准确。例如,参见第6章,高级字符驱动程序操作。

是的,此代码在
准备到等待
计划
之间运行,应检查状态。另外,当使用
准备等待
时,
添加等待队列
是多余的。你在哪里找到这个代码的?@Tsyvarev似乎在第59页。是的,这个代码在
prepare\u to\u wait
schedule
之间运行,应该检查状态。另外,当使用
准备等待
时,
添加等待队列
是多余的。你在哪里找到这个密码的?@Tsyvarev似乎在第59页。