源出处:http://www.startos.com/linux/tips/2011011921499_5.html
/**
* wait_event_interruptible - sleep until a condition gets true
* @wq: the waitqueue to wait on
* @condition: a C expression for the event to wait for
*
* The process is put to sleep (TASK_INTERRUPTIBLE) until the
* @condition evaluates to true or a signal is received.
* The @condition is checked each time the waitqueue @wq is woken up.
*
* wake_up() has to be called after changing any variable that could
* change the result of the wait condition.
*
* The function will return -ERESTARTSYS if it was interrupted by a
* signal and 0 if @condition evaluated to true.
*/
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
3.4 wait_event_interruptible_timeout
#define __wait_event_interruptible_timeout(wq,condition,ret) \
do { \
DEFINE_WAIT(__wait); \
\
for (;;) { \
prepare_to_wait(&wq,&__wait,TASK_INTERRUPTIBLE); \
if (condition) \
break; \
if(!signal_pending(current)) { \
// 当前进程无信号需要处理
ret = schedule_timeout(ret); \
if(!ret) \
break; //时间片用完唤醒 \
continue; \ .
} \
ret = _ERESTARTSYS; //被信号唤醒 \
break; \
} \
finish_wait(&wq,&__wait); \
} while (0)
#define wait_event_interruptible_timeout(wq,condition,timeout) \
( { \
long__ret = timeout; \
if(!(condition)) \
__wait_event_interruptible_timeout(wq,condition,__ret); \
__ret; \
})
wait_event_interruptible_timeout()类架构:
4 唤醒系列wake_up
4.1 wake_up 的API
惯例:用 wake_up 唤醒 wait_event;用 wake_up_interruptible 唤醒wait_event_interruptible。很少会需要调用wake_up_interruptible 之外的唤醒函数,但为完整起见,这里是整个集合:
wake_up(wait_queue_head_t *queue); wake_up_interruptible(wait_queue_head_t *queue); /*wake_up 唤醒队列中的每个非独占等待进程和一个独占等待进程。wake_up_interruptible 同样, 但它跳过处于不可中断休眠的进程。它们在返回之前, 使一个或多个进程被唤醒、被调度(如果它们被从一个原子上下文调用, 这就不会发生).*/
--------------------------------------------------------------------------------
wake_up_nr(wait_queue_head_t *queue, int nr); wake_up_interruptible_nr(wait_queue_head_t *queue, int nr); /*这些函数类似 wake_up, 除了它们能够唤醒多达 nr 个独占等待者, 而不只是一个. 注意传递 0 被解释为请求所有的互斥等待者都被唤醒*/
--------------------------------------------------------------------------------
wake_up_all(wait_queue_head_t *queue); wake_up_interruptible_all(wait_queue_head_t *queue); /*这种 wake_up 唤醒所有的进程, 不管它们是否进行独占等待(可中断的类型仍然跳过在做不可中断等待的进程)*/
--------------------------------------------------------------------------------
wake_up_interruptible_sync(wait_queue_head_t *queue); /*一个被唤醒的进程可能抢占当前进程, 并且在 wake_up 返回之前被调度到处理器。 但是, 如果你需要不要被调度出处理器时,可以使用 wake_up_interruptible 的"同步"变体. 这个函数最常用在调用者首先要完成剩下的少量工作,且不希望被调度出处理器时。*/