wait queue 笔记

1.正在运行的task从run queue上下来后,被放到wait queue上,从而进入睡眠。

 

 

typedef struct __wait_queue wait_queue_t;

typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key);

int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);

 

struct __wait_queue { //wait queue 中的每个节点的数据结构

unsigned int flags;

#define WQ_FLAG_EXCLUSIVE 0x01

void *private;

wait_queue_func_t func;

struct list_head task_list;

};

 

 

 

struct __wait_queue_head {//wait queue 的头节点

spinlock_t lock;

struct list_head task_list;

};

typedef struct __wait_queue_head wait_queue_head_t;

 

 

简单使用wait_queue

 

 1.DECLARE_WAIT_QUEUE_HEAD(name);

 

或者等价使用

wait_queue_head_t my_queue;

init_waitqueue_head(&my_queue);//定义等待队列头

 

2.想要阻塞的task调用wait_event_interruptible(&my_queue,contion)即可

调用wake_up(&my_queue)可将等待队列里所有的进程唤醒,进程被唤醒后,判断如果contion为假则继续睡眠。

 

 

 

/**

 * 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; /

})

 

#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); ///将节点从等待队列中移除,并将进程设置成task_running

} while (0)

 

 

自己操作wait_queue

全局定义等待队列头

1. wait_queue_head_t test_head;//定义wait queue 头

    init_waitqueue_head(&test_head);//初始化wait queue 头

 

需要阻塞的进程

2.       DECLARE_WAITQUEUE(wait,current);//定义等待队列节点

          add_wait_queue(&test_head,&wait);//添加到等待队列

          set_task_state(current,TASK_INTERRUPTIBLE);//改变进程状态

          printk(KERN_ALERT"process %s state is %d/n",current->comm,current    ->state);

          schedule();//让出cpu

          remove_wait_queue(&test_head,&wait);//被其他进程唤醒后,将等待节点从等待队列中移除。

执行唤醒的进程

3.     wake_up_interruptible(&test_head);将在等待队列上的进程都唤醒

 

 

以上讨论的wait queue 都是wake_up操作将所有在队列内的等待进程唤醒。如果 节点以 Exclusive waits 方式加入等待队列的话

那样调用wake_up只会唤醒到第一次遇到exclusive方式的节点。

add_wait_queue_exclusive()将节点以execlusive方式加入节点。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值