解析Linux内核的同步与互斥机制(五)

源出处: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 的"同步"变体. 这个函数最常用在调用者首先要完成剩下的少量工作,且不希望被调度出处理器时。*/

你可能感兴趣的:(解析Linux内核的同步与互斥机制(五))