2020-04-26 11:10:38 +08:00
|
|
|
|
# Linux Kernel 等待队列
|
|
|
|
|
|
2020-04-28 11:41:57 +08:00
|
|
|
|
**头文件:**
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
#include <linux/wait.h>
|
|
|
|
|
```
|
|
|
|
|
|
2020-04-26 11:10:38 +08:00
|
|
|
|
## wait_event_interruptible_timeout 函数
|
|
|
|
|
|
|
|
|
|
**函数原型:**
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
#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 函数
|
|
|
|
|
|
|
|
|
|
**函数原型:**
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
## 示例
|
|
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
```
|