Linux 等待队列 init_waitqueue_head 和 wait_event_interruptible

本文介绍了Linux驱动程序中如何使用等待队列(wait_queue)进行进程的阻塞与唤醒。通过示例代码展示了如何初始化等待队列头,使用wait_event_interruptible和wait_event_timeout函数进行事件中断和超时中断,并给出了设备初始化函数、数据写入函数以及线程函数的实现。这些函数在条件不满足时使进程进入休眠状态,条件满足或超时后唤醒进程继续执行。

本文参考: https://www.sohu.com/a/258717832_781584

在 Linux 驱动程序中,可以使用等待队列(wait queue)来实现阻塞进程的唤醒。

1 头文件

#include <linux/sched.h>
#include <linux/wait.h>

2. 定义“等待队列头”

wait _ queue _ head _ t my _ queue;

3. 初始化“等待队列头”。

void init_waitqueue_head(wait_queue_head_t *);

而下面的 DECLARE_WAIT_QUEUE_HEAD()宏可以作为定义并初始化等待队列头的“快捷方式”。

DECLARE_WAIT_QUEUE_HEAD(name);

4. 超时中断方法

当cond条件是false,则休眠(超时版,timeout是超时值,单位是计数值),超时返回值为0 ,被唤醒。

int wait_event_timeout(wait_queue_head_t wq, int condition, unsigend long timeout);

5. 事件中断方法

当cond条件是false,则休眠

int wait_event_interruptible(wait_queue_head_t wq, int condition);

/************** 示例代码 ******************/

static wait_queue_head_t mthread_wq; // 等待队列头定义
static struct task_struct *mthread_task = NULL; // 线程


// 这是一个 device init 函数,可以在这里初始化等待队列头
static int __init mydev_init(void)
{
    init_waitqueue_head(&mthread_wq); // 初始化等待队列头
    mthread_task = kthread_create(m_thread, (void *)&mbuf,"mdev");
    
    return 0;
}
arch_initcall(mydev_init);


// 这个函数的动作,会触发cond满足条件,进而触发中断
void m_write_data(void) {
   if(mthread_task){
        // do something ...
        wake_up_interruptible(&mthread_wq);  // 唤醒等待队列
   }
}
EXPORT_SYMBOL_GPL(m_write_data);


// 等待队列中的线程函数
static int m_thread(void *data){
    while(1){
        wait_event_interruptible(mthread_wq, (cond)); //等待队列中断, 当cond == true 时,会往下跑
        // do something your warn here ......
    }
    mthread_task = NULL; // 线程跳出 while(1)时,表示线程生命周期结束了,注销掉
    return 0;
}

6. 事件+超时中断方法

int wait_event_interruptible_timeout(wait_queue_head_t wq, int condition, unsigend long timeout);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值