使用wait_event_interruptible,何时会被唤醒?

1. 关于 wait_event_interruptible() 和 wake_up()的使用

读一下wait_event_interruptible()的源码,不难发现这个函数先将 
当前进程的状态设置成TASK_INTERRUPTIBLE,然后调用schedule(), 
而schedule()会将位于TASK_INTERRUPTIBLE状态的当前进程从runqueue 
队列中删除。从runqueue队列中删除的结果是,当前这个进程将不再参 
与调度,除非通过其他函数将这个进程重新放入这个runqueue队列中, 
这就是wake_up()的作用了。 
  
由于这一段代码位于一个由condition控制的for(;;)循环中,所以当由 
shedule()返回时(当然是被wake_up之后,通过其他进程的schedule()而 
再次调度本进程),如果条件condition不满足,本进程将自动再次被设 
置为TASK_INTERRUPTIBLE状态,接下来执行schedule()的结果是再次被 
从runqueue队列中删除。这时候就需要再次通过wake_up重新添加到 
runqueue队列中。 
  
如此反复,直到condition为真的时候被wake_up. 
  
可见,成功地唤醒一个被wait_event_interruptible()的进程,需要满足: 
  
   在 1)condition为真的前提下,2) 调用wake_up()。 
2. 关于wait_event_interruptible的返回值 

根据 wait_event_interruptible 的宏定义知: 
  
   1) 条件condition为真时调用这个函数将直接返回0,而当前进程不会 
      被 wait_event_interruptible和从runqueue队列中删除。 
  
   2) 如果要被wait_event_interruptible的当前进程有nonblocked pending 
      signals, 那么会直接返回-ERESTARTSYS(i.e. -512),当前进程不会 
      被wait_event_interruptible 和从runqueue队列中删除。 
  
   3) 其他情况下,当前进程会被正常的wait_event_interruptible,并从 
      runqueue队列中删除,进入TASK_INTERRUPTIBLE状态退出运行调度, 
      直到再次被唤醒加入runqueue队列中后而参与调度,将正常返回0。

附1:wait_event_interruptible  宏 
  
#define wait_event_interruptible(wq, condition)    \ 
({                                                 \ 
     int __ret = 0;                                  \ 
     if (!(condition))                               \ 
      __wait_event_interruptible(wq, condition, __ret); \ 
      __ret;                                         \ 
}) 

你可能感兴趣的:(使用wait_event_interruptible,何时会被唤醒?)