NotePublic/Software/Development/OperatingSystem/Linux/Kernel/API/Linux_Kernel_等待队列.md

2.2 KiB
Raw Blame History

Linux Kernel 等待队列

头文件:

#include <linux/wait.h>

wait_event_interruptible_timeout 函数

函数原型:

#define wait_event_interruptible_timeout(wq_head, condition, timeout) \
({ \
  long __ret = timeout; \
  might_sleep(); \
  if (!___wait_cond_timeout(condition)) \
    __ret = __wait_event_interruptible_timeout(wq_head, \
                  condition, timeout); \
    __ret; \
})

说明:

睡眠到 condition 为真,或超时。支持可中断的睡眠,意味着可以发送信号给睡眠的进程,进程会对信号进行响应。

参数:

wq要等待的等待队列

condition等待事件发生的条件一个C表达式

timeout超时时间

返回值:

当返回值大于 0 时,表示返回的是剩余的时间(以 jiffy为单位条件满足也就是还未超时条件已经达成了被唤醒了。

当返回值为 0 时,表示超时,自动唤醒,此时根据情况进行错误处理吧。

wake_up_interruptible 函数

函数原型:

void wake_up_interruptible (wait_queue_head_t *q);

说明:

唤醒 q 指定的注册在等待队列上的进程。该函数不能直接的立即唤醒进程,而是由调度程序转换上下文,调整为可运行状态。

参数:

q等待队列变量指针。

返回值:

wake_up_interruptible

wake_up_interruptible_nr

wake_up_interruptible_all

wake_up_interruptible_sync

示例

wait_queue_head_t wq;
uint8_t condition = 0;
uint64_t timeout_jf = 500;

/**
 * @brief 初始化函数
 * @return
 */
void init_func()
{
    init_waitqueue_head(&wq);
}

/**
 * @brief 谋过程调用中需要等待中断
 * @return 成功或失败
 */
ssize_t xxx_func()
{
    int32_t err;
    ssize_t ret = 0;

    err = wait_event_interruptible_timeout(wq, (condition== 1), timeout_jf);
    if (err == 0)
        ret = -ETIMEDOUT;
    else if (err < 0)
        ret = -EINTR;

    return ret;
}

/**
 * @brief 中断处理函数
 */
void irq_handle()
{
    condition = 1U;
    wake_up_interruptible(&wq);
}