Linux等待队列

等待队列主要用于:当任务(进程)由于某个条件得不到满足时,为避免不必要的轮询,使得进程在等待期间进入睡眠状态,直到等待的条件得到满足时由内核唤醒,进入运行状态。

等待队列是基于双循环链表structlist_head来实现的,与进程调度机制紧密结合,能够用于实现核心的异步事件通知机制。

数据结构



struct __wait_queue
{
    unsigned int flags;           /*0:非互斥进程,0x01:互斥进程*/
#define WQ_FLAG_EXCLUSIVE   0x01  /*表示等待进程想要被独占地唤醒*/
    void *private;                /*指向等待进程的task_struct实例*/
    wait_queue_func_t func;       /*用于唤醒等待进程*/
    struct list_head task_list;   /*将wait_queue_t添加到wait_queue_head_t*/
};
typedef struct __wait_queue wait_queue_t;/*等待队列项*/
struct __wait_queue_head
{
    spinlock_t lock;
    struct list_head task_list;
};
typedef struct __wait_queue_head wait_queue_head_t;/*等待队列头*/

         Linux等待队列的实现思想:当一个任务(进程)需要在某个等待队列wait_queue_head_t上睡眠时,将自己的进程控制块信息封装到等待队列项wait_queue_t中,然后挂载到wait_queue_head_t的链表中,执行调度睡眠。当等待的某个事件发生后,另一个任务(进程)会唤醒等待队列wait_queue_head_t上的某个任务或所有任务,唤醒工作即是将等待队列中的任务设置为可调度状态,并且从队列中删除。


2 函数

2.1  初始化等待队列

void init_waitqueue_head(wait_queue_head_t *q);

2.2   等待事件

#define __wait_event(wq, condition)                     \

do {                                    \

    DEFINE_WAIT(__wait);                        \

                                    \

    for (;;) {                          \

        prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \

        if (condition)                      \

            break;                      \

        schedule();                     \

    }                               \

    finish_wait(&wq, &__wait);                  \

} while (0)

 

#define wait_event(wq, condition)                   \

do {                                    \

    if (condition)                          \

        break;                          \

    __wait_event(wq, condition);                    \

} while (0)


等待事件函数

描述

wait_event(wq,condition)

进程状态被设置为

TASK_UNINTERRUPTIBLE,进入睡眠

wait_event_interruptible(wq, condition)

设进程为TASK_INTERRUPTIBLE状态,睡眠期间被信号唤醒则返回-ERESTARTSYS错误码

wait_event_interruptible_exclusive(wq, condition)

睡眠的为互斥进程

wait_event_timeout(wq, condition, timeout)

超时返回0

wait_event_interruptible_timeout(wq, condition, timeout)

睡眠期间被信号唤醒则返回ERESTARTSYS错误码

2.3  唤醒等待进程

#define wake_up(x)          __wake_up(x, (unsigned int)(TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE), 1, NULL)


唤醒函数

描述

wake_up(x)

可唤醒进程状态为TASK_UNINTERRUPTIBLETASK_INTERRUPTIBLE的进程,与wait_eventwait_event_timeout成对使用

wake_up_all(x)

唤醒所有等待的进程

wake_up_interruptible(x)

仅唤醒进程状态为TASK_INTERRUPTIBL的进程,与wait_event_interruptiblewait_event_interruptible_timeout成对使用





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值