Linux中等待队列的实现

Linux下的共享外设中断|等待队列|通过中断实现按键消抖 1.包含相关的头文件2. 申请中断号3.注册中断服务函数函数参数irq: 中断号函数参数int: 产生中断的中断号void *: 传递给中断服务函数的参数函数返回值我们不用, 给个 0 即可flags: 中断触发标志IRQ_TYPE_EDGE_RISING --- 上升沿触发IRQ_TYPE_EDGE_FALLING --- 下降沿触发IRQ_TYPE_EDGE_BOTH --- 双边沿。 阅读详情

   在软件开发中任务经常由于某种条件没有得到满足而不得不进入睡眠状态,然后等待条件得到满足的时候再继续运行,进入运行状态。这种需求需要等待队列机制的支持。Linux中提供了等待队列的机制,该机制在内核中应用很广泛。

       在Linux内核中使用等待队列的过程很简单,首先定义一个wait_queue_head,然后如果一个task想等待某种事件,那么调用wait_event(等待队列,事件)就可以了。
     等待队列应用广泛,但是内核实现却十分简单。其涉及到两个比较重要的数据结构:__wait_queue_head,该结构描述了等待队列的链头,其包含一个链表和一个原子锁,结构定义如下:

struct __wait_queue_head {
    

      spinlock_t lock;                    /* 保护等待队列的原子锁 */

      struct list_head task_list;          /* 等待队列 */

};

__wait_queue,该结构是对一个等待任务的抽象。每个等待任务都会抽象成一个wait_queue,并且挂载到wait_queue_head上。该结构定义如下:

struct __wait_queue {

 unsigned int flags;

 void *private;                       /* 通常指向当前任务控制块 */

/* 任务唤醒操作方法,该方法在内核中提供,通常为autoremove_wake_function */

 wait_queue_func_t func;             

 struct list_head task_list;              /* 挂入wait_queue_head的挂载点 */

};

        Linux中等待队列的实现思想如下图所示,当一个任务需要在某个wait_queue_head上睡眠时,将自己的进程控制块信息封装到wait_queue中,然后挂载到wait_queue的链表中,执行调度睡眠。当某些事件发生后,另一个任务(进程)会唤醒wait_queue_head上的某个或者所有任务,唤醒工作也就是将等待队列中的任务设置为可调度的状态,并且从队列中删除。

点击看大图


    使用等待队列时首先需要定义一个wait_queue_head,这可以通过DECLARE_WAIT_QUEUE_HEAD宏来完成,这是静态定义的方法。该宏会定义一个wait_queue_head,并且初始化结构中的锁以及等待队列。当然,动态初始化的方法也很简单,初始化一下锁及队列就可以了。

       一个任务需要等待某一事件的发生时,通常调用wait_event,该函数会定义一个wait_queue,描述等待任务,并且用当前的进程描述块初始化wait_queue,然后将wait_queue加入到wait_queue_head中。函数实现流程说明如下:

1、用当前的进程描述块(PCB)初始化一个wait_queue描述的等待任务。

2、在等待队列锁资源的保护下,将等待任务加入等待队列。

3、判断等待条件是否满足,如果满足,那么将等待任务从队列中移出,退出函数。

4、 如果条件不满足,那么任务调度,将CPU资源交与其它任务。

5、 当睡眠任务被唤醒之后,需要重复(2)、(3)步骤,如果确认条件满足,退出等待事件函数。

等待队列编程接口

 

 

序号



 

编程接口



 

使用说明




 

 

1



 

wait_event



 

这是一个宏,让当前任务处于等待事件状态。输入参数如下:

 

@wq:等待队列

 

@conditions:等待条件




 

 

2



 

wait_event_timeout



 

功能与wait_event类似,多了一个超时机制。参数中多了一项超时时间。




 

 

3



 

wait_event_interruptible



 

这是一个宏,与前两个宏相比,该宏定义的等待能够被消息唤醒。如果被消息唤醒,那么返回- ERESTARTSYS。输入参数如下:

 

@wq:等待队列

 

@condition:等待条件

 

@rt:返回值




 

 

4



 

wait_event_interruptible_timeout



 

与(3)相比,多了超时机制




Linux 内核等待队列(wait queue)机制详解 本文介绍了Linux内核中的等待队列机制,该机制通过wait_queue_head和wait_queue_entry数据结构实现进程/线程的睡眠与唤醒。等待队列广泛应用于驱动、内存管理等领域,支持普通、独占和优先级等唤醒策略。文章详细讲解了等待队列的声明初始化、使用流程(睡眠/唤醒)、高级用法(条件等待宏)及内核实现原理,包括链表结构、并发保护等。最后总结了典型应用场景和使用建议,强调合理选择唤醒方式、防范死锁竞态等问题。等待队列是Linux内核实现高效并发同步的核心机制之一。 阅读详情

相关推荐

Linux的等待队列介绍

介绍等待队列的管理,如何初始化,如何添加一个等待队列entry,希望对学习者有帮助。

进程间通信之消息队列

消息队列现在我们来讨论第三种也是最后一种System V IPV工具:消息队列。在许多方面看来,消息队列类似于有名管道,但是却没有与打开与关闭管道的复杂关联。然而,使用消息队列并没有解决我们使用有名管道所遇到的问题,例如管道上的阻塞。消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法。与有名管道比较起来,消息队列的优点在独立于发送与接收进程,这减少了在打开与关

4492

find命令

命令是 Linux/Unix 系统中用于搜索文件和目录的强大工具,支持多种搜索条件组合,并能对搜索结果执行各种操作。以下是其详细说明、常用参数及示例: 搜索路径:指定起始目录(如 、 或 表示当前目录)。 查找条件:基于文件名、类型、大小、时间等属性过滤。 处理动作:对匹配结果执行操作(如打印、删除、执行命令等)。 常用参数及示例 1. 按名称查找 :区分大小写匹配文件名。 :不区分大小写匹配文件名。 2. 按文件类型查找 :指定文件类型。 文件类型: :普通文件 :目录 :符号链接

qiao2458的博客 1136

Linux中的工作队列

Linux中的工作队列  [前记]Linux自从2.6.20之后,工作队列发生了一些变化,目前从网络上搜索的资料一般都是介绍老版本的工作队列,很少见到对新版本的介绍。本文对新老版本都做了简要概述,并分别提供了简单的实作案例。******************************************************

doujiao的专栏 1003

【Linux 驱动开发】STM32MP1 LCD 显示系统完整实践指南

STM32MP1 LCD显示系统实践指南 本文全面介绍STM32MP1平台实现MIPI DSI LCD显示的完整流程,涵盖硬件连接、设备树配置、显示原理和驱动实现。主要内容包括: 硬件连接:详细说明MIPI DSI差分对、背光PWM、复位/供电管脚的连接方式 设备树配置: PWM背光控制节点设置 LTDC与DSI端口映射关系 Panel节点参数定义 显示基础:讲解LCD/OLED显示原理、常见接口类型(RGB/LVDS/MIPI/HDMI)及信号时序 驱动实现。

猫猫的小茶馆 495

在Ultralytics YOLO中添加/更换模块详细指南

使用参数继承 my_module_args: &my_args [64, 3, 0.5] # 定义参数模板 backbone: - [-1, 1, MyModule, *my_args] # 引用参数。

MR_Colorful的博客 2584

linux内核中等待队列 (函数wait_event与wake_up)

根据内核3.1.6版本源码、书籍和网上资料,对几个函数进行分析 介绍这几个函数,不得不先介绍等待队列wait_queue_head_t与完成量completion。 等待队列用于使得进程等待某一特定事件的发生,无需频繁的轮询,进程在等待周期中睡眠,当时间发生后由内核自动唤醒。 完成量机制是基于等待队列的,内核利用该机制等待某一...

weixin_30361641的博客 882

别再只用三次多项式了!用MATLAB手把手教你搞定七次多项式轨迹规划(附完整代码)

本文详细介绍了七次多项式在轨迹规划中的优势与应用,通过MATLAB实现从理论推导到实际代码的全过程。相比传统的三次多项式,七次多项式能精确控制位置、速度、加速度和加加速度,实现更平滑的运动控制,特别适用于工业机器人和数控机床等高精度场景。文章包含完整的MATLAB代码示例和优化技巧,帮助工程师快速掌握这一高级轨迹规划方法。

weixin_30872337的博客 298

分清概念十分重要之--Linux中的各种队列

先列个框架,后续丰富完善。 提这个问题,是因为在Linux内核学习中,遇到过一个让人啼笑皆非的问题。这个问题是啥呢?提个引子,在实际生活中,可能每个人都有过这样的经历,就是总是将某两个明明完全不同的概念搞混。原因有可能是两个概念发音比较接近,或者字形相似,亦或者没有什么相似点,而只是在大脑中奇怪的产生了关联而已,就像量子作用。 回到开头,说说我的这个问题。有一段时间,对于Linux中将wait_queue加入等待队列头,然后再等待被唤醒的逻辑总是想不清楚,直到后来有一天突然搞明白,我是将等待队列和工作队

wwwyuewww的专栏 1733

洛奇 服务器文件,MabinogiG20S2 [洛奇G20服务端]

Code:Titles:>set_title /id: /add /remove Parameters for titles>set_title /id:60001 /add add devcat title>set_title /id:60001 /remove remove devcat title===========================...

weixin_30813385的博客 4307

02-Cesium-实现天地图标记

首先天地图申请token,然后Cesium-实现天地图标记详细说明

m0_62785037的博客 1171

linux中通过等待队列来实现阻塞

linux中,可以用wait_queue来实现阻塞。

tmkeepgood的专栏 847

HAL库:中断处理函数 及 weak弱声明中断回调函数 详解

HAL库中断处理函数 及 weak弱声明中断回调函数

L_Z_J_I的博客 5170

linux驱动——等待队列实现阻塞访问

当一个进程/线程访问共享资源(如缓冲区、设备等)时,如果资源不可用,线程会挂起自己,并将自己放入等待队列,当资源可用时,操作系统会唤醒等待队列中的线程,这可以提高CPU利用率和系统性能。DECLARE_WAIT_QUEUE_HEAD(name)宏用于定义和初始化一个等待队列头,名字为my_wait_queue。buffer_not_empty:条件表达式,若为false,线程将休眠,若为true,线程不休眠。

2401_84888945的博客 431

Bean named‘ddlApplicationRunner‘is expected to be of type ‘org.springframework.boot.Runner‘

springboot3.1.7整合mybatisplus3.5.3.2版本报错,sringboot3.x整合myabtis报错

雾林小妖的博客 1万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

linux中等待队列的实现

Linux内核的等待队列是以双循环链表为基础数据结构,与进程调度机制紧密结合,能够用于实现核心的异步事件通知机制。 在这个链表中,有两种数据结构:等待队列头(wait_queue_head_t)和等待队列项(wait_queue_t)。等待队列头和等待队列项中都包含一个list_head类型的域作为"连接件"。它通过一个双链表和把等待tast的头,和等待的进程列表链接起来。从上图可以清晰看到。所

他山之石,可以攻玉 721

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Linux等待队列原理与实现

当进程要获取某些资源(例如从网卡读取数据)的时候,但资源并没有准备好(例如网卡还没接收到数据),这时候内核必须切换到其他进程运行,直到资源准备好再唤醒进程。就是内核用于管理等待资源的进程,当某个进程获取的资源没有准备好的时候,可以通过调用。可以看出,唤醒等待队列就是变量等待队列的等待进程,然后调用唤醒函数来唤醒它们。当资源准备好后,就可以唤醒等待队列中的进程,可以通过。函数可以使当前进程让出CPU,切换到其他进程执行。添加等待进程,首先要声明一个。函数把节点添加到等待队列即可。函数来唤醒等待队列中的进程。

m0_74282605的博客 481

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【Linux驱动】Linux阻塞IO —— 阻塞读取按键状态(等待队列实现)

【Linux驱动】Linux阻塞IO —— 阻塞读取按键状态(等待队列实现)

challenglistic的博客 1518

linux等待队列用法,Linux等待队列原理与实现

当进程要获取某些资源(例如从网卡读取数据)的时候,但资源并没有准备好(例如网卡还没接收到数据),这时候内核必须切换到其他进程运行,直到资源准备好再唤醒进程。waitqueue (等待队列) 就是内核用于管理等待资源的进程,当某个进程获取的资源没有准备好的时候,可以通过调用 add_wait_queue() 函数把进程添加到 waitqueue 中,然后切换到其他进程继续执行。当资源准备好,由资...

weixin_33514221的博客 331

linux内核队列实现方式,Linux内核等待队列机制原理分析

1.等待队列数据结构等待队列由双向链表实现,其元素包括指向进程描述符的指针。每个等待队列都有一个等待队列头(wait queue head),等待队列头是一个类型为wait_queque_head_t的数据结构:struct __wait_queue_head {spinlock_t lock;struct list_head task_list;};typedef struct __wait_q...

weixin_31491059的博客 242

Linux源码剖析——等待队列原理与实现

当进程要获取某些资源(例如从网卡读取数据)的时候,但资源并没有准备好(例如网卡还没接收到数据),这时候内核必须切换到其他进程运行,直到资源准备好再唤醒进程。就是内核用于管理等待资源的进程,当某个进程获取的资源没有准备好的时候,可以通过调用函数把进程添加到waitqueue中,然后切换到其他进程继续执行。当资源准备好,由资源提供方通过调用wake_up()函数来唤醒等待的进程。

白话机器学习 273

嵌入式学习之Linux驱动 使用等待队列实现阻塞访问

TheAnswerisy的博客 204

Linux驱动阻塞式IO实现与等待队列原理

阻塞式IO是Linux设备驱动中实现高效事件响应的核心机制,其本质是进程状态切换与内核调度器协同的结果。通过等待队列(wait queue)这一关键抽象,驱动可将用户进程挂起于TASK_INTERRUPTIBLE状态,避免CPU空转轮询,显著降低系统负载。该机制依托原子操作保障中断/进程上下文并发安全,并需精确配对wake_up_interruptible()与wait_event_interruptible()以防止唤醒丢失。在嵌入式场景如按键驱动中,它支撑低功耗、高响应的交互体验;同时为select/e

weixin_33239721的博客 111
上一篇: Linux的软中断处理实现
下一篇: Workqueue机制的实现
kobbee9
博客等级 码龄16年 26粉丝 2原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值