Linux内核之等待队列wait_queue_head_t数据结构用法实例(四十)

本文介绍了Linux内核中的wait_queue_head_t数据结构,包括其在实现等待队列中的关键作用,以及如何使用wait_event_interruptible和wait_event_interruptible_timeout进行进程同步。通过代码实例演示了如何在驱动程序中运用这些功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🌻1.前言

本篇目的:Linux内核之等待队列wait_queue_head_t用法实例

🌻2.Linux内核之等待队列wait_queue_head_t介绍

  • wait_queue_head_t 是 Linux 内核中用于实现等待队列的基本数据结构。在 Linux 内核中,等待队列是一种常见的机制,用于让进程在某个条件不满足时进入睡眠状态,当条件满足时被唤醒继续执行。这种机制在很多内核子系统中都有应用,如进程调度、设备驱动、同步等。
  • wait_queue_head_t 结构体定义了一个等待队列的头部,它包含了等待队列的基本信息和一个用于同步的锁。等待队列实际上是一个进程列表,这些进程都在等待某个条件变为真。每个等待队列都有一个对应的 wait_queue_head_t 结构体,用于管理这个队列。
  • 在 Linux 内核中,可以通过 DECLARE_WAIT_QUEUE_HEAD 宏来静态地声明一个 wait_queue_head_t 对象,也可以通过 init_waitqueue_head 函数动态地初始化一个 wait_queue_head_t 对象。初始化后,可以通过 wait_eventwait_event_interruptiblewait_event_timeout 等函数将进程加入到等待队列中,这些函数会阻塞进程,直到指定的条件变为真或超时。
  • 当条件满足时,需要调用 wake_upwake_up_interruptible 等函数来唤醒等待队列中的进程。这些函数会遍历等待队列中的所有进程,并设置它们的唤醒标志,然后唤醒它们。
  • wait_queue_head_t 结构体的定义如下:
typedef struct __wait_queue_head {
    spinlock_t lock;
    struct list_head task_list;
} wait_queue_head_t;
  • 其中,spinlock_t 是一个自旋锁,用于同步对等待队列的操作;struct list_head 是一个双向链表,用于存储等待队列中的进程。
  • 在 Linux 内核中,等待队列的使用非常广泛。例如,在进程调度中,等待队列用于实现等待某个进程的状态变化(如等待子进程退出);在设备驱动中,等待队列用于实现等待设备准备好读写;在文件系统中,等待队列用于实现等待文件的锁定状态变化等。
  • 总之,wait_queue_head_t 是 Linux 内核中实现等待队列的关键数据结构,它为内核提供了一种简单有效的同步机制,使得内核能够以优雅的方式处理各种同步问题。

🌻3.代码实例

以下为:Linux内核驱动程序中使用 wait_queue_head_t 数据结构和相关的等待函数来实现进程同步。

🐓3.1 wait_event_interruptible() 实现等待队列

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/kthread.h>

MODULE_LICENSE("GPL");

static wait_queue_head_t my_wait_queue;
static int condition = 0;

static int my_thread_function(void *data) {
    printk(KERN_INFO "Thread started\n");
    wait_event_interruptible(my_wait_queue, condition != 0);
    printk(KERN_INFO "Thread awakened\n");
    return 0;
}

static int __init my_init(void) {
    printk(KERN_INFO "Module init\n");
    init_waitqueue_head(&my_wait_queue);
    kthread_run(my_thread_function, NULL, "my_thread");
    msleep(5000); // Simulate some work
    condition = 1; // Set the condition
    wake_up(&my_wait_queue); // Wake up waiting thread
    return 0;
}

static void __exit my_exit(void) {
    printk(KERN_INFO "Module exit\n");
}

module_init(my_init);
module_exit(my_exit);

🐓3.2 wait_event_interruptible_timeout() 实现超时等待

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/kthread.h>

MODULE_LICENSE("GPL");

static wait_queue_head_t my_wait_queue;
static int condition = 0;

static int my_thread_function(void *data) {
    printk(KERN_INFO "Thread started\n");
    wait_event_interruptible_timeout(my_wait_queue, condition != 0, 5000); // Wait for 5 seconds
    if (condition != 0)
        printk(KERN_INFO "Condition met\n");
    else
        printk(KERN_INFO "Timeout occurred\n");
    return 0;
}

static int __init my_init(void) {
    printk(KERN_INFO "Module init\n");
    init_waitqueue_head(&my_wait_queue);
    kthread_run(my_thread_function, NULL, "my_thread");
    msleep(7000); // Simulate some work
    condition = 1; // Set the condition
    wake_up(&my_wait_queue); // Wake up waiting thread
    return 0;
}

static void __exit my_exit(void) {
    printk(KERN_INFO "Module exit\n");
}

module_init(my_init);
module_exit(my_exit);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Android系统攻城狮

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值