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

释放双眼,带上耳机,听听看~!

/**

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

给TA打赏
共{{data.count}}人
人已打赏
安全运维

WordPress网站专用docker容器环境带Waf

2020-7-18 20:04:44

安全运维

运维安全-Gitlab管理员权限安全思考

2021-9-19 9:16:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索