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

3602

被折叠的 条评论
为什么被折叠?



