linux内核的 等待队列 使用方法,wait_queue_head_t,进程休眠

2023-11-15

当你在用户空间需要读写一大片数据的时候,这个就用上了。

以下来自:http://www.yuanma.org/data/2006/1207/article_1916.htm

假设我们在 kernel 里产生一个 buffer,user 可以经由 read,write 等 system call 来读取或写资料到这个 buffer 里。如果有一个 user 写资料到 buffer 时,此时 buffer 已经满了。那请问你要如何去处理这种情形呢 ? 第一种,传给 user 一个错误讯息,说 buffer 已经满了,不能再写入。第二种,将 user 的要求 block 住, 等有人将 buffer 内容读走,留出空位时,再让 user 写入资料。但问题来了,你要怎么将 user 的要求 block 住。难道你要用
 while ( is_full );
write_to_buffer;
这样的程序代码吗? 想想看,如果你这样做会发生什么事? 第一,kernel会一直在这个 while 里执行。第二个,如果 kernel 一直在这个 while 里执行,表示它没有办法去 maintain系统的运作。那此时系统就相当于当掉了。在这里 is_full 是一个变量,当然,你可以让 is_full 是一个 function,在这个 function里会去做别的事让 kernel 可以运作,那系统就不会当。这是一个方式。还有,你说可以在while里面把buffer里的内容读走,再把is_full的值改了,但是我们会可能把重要的数据在我们不想被读的时候被读走了,那是比较麻烦的,而且很不灵活.如果我们使用 wait_queue 的话,那程序看起来会比较漂亮,而且也比较让人了解,如下所示:
 
struct wait_queue_head_t wq; /* global variable */
DECLARE_WAIT_QUEUE_HEAD (wq);
 
while ( is_full ){
interruptible_sleep_on( &wq );
} write_to_buffer();
 

interruptible_sleep_on( &wq ) 是用来将目前的 process,也就是要求写资料到buffer 的 process放到 wq 这个 wait_queue 里。在 interruptible_sleep_on 里,则是最后会呼叫 schedule() 来做 schedule 的动作,谁调用了schedule谁就趴下,让别人去运行,醒来就原地起来,执行schedule()后的代码。那那个调用了schedule的家伙什么醒过来呢?这时候就需要用到另一个函数了wake_up_interruptible()了。

以下来自:http://tauruspdj.blog.163.com/blog/static/4312500620090794030998/

linux中最简单的休眠方式是下面的宏,
wait_event(queue, condition)  /* 进程将被置于非中断休眠(uninterruptible sleep)*/
wait_event_interruptible(queue, condition) /*进程可被信号中断休眠,返回非0值表示休眠被信号中断*/
wait_event_timeout(queue, condition, timeout)    /*等待限定时间jiffy,condition满足其一返回0*/
wait_event_interruptible_timeout(queue, condition, timeout)
queue是等待队列头,传值方式
condition是任意一个布尔表达式,在休眠前后多次对condition求值,为真则唤醒

唤醒进程的基本函数是wake_up
void wake_up(wait_queue_head_t *queue);     /*唤醒等待在给定queue上的所有进程*/
void wake_up_interruptible(wait_queue_head_t *queue);

实践中,一般是wait_event和 wake_up, wait_event_interruptible和 wake_up_interruptible 成对使用。

【补充】其实看了那么多,他们也没有给个立即可用的步骤,写blog嘛,就是分享心得。我基于2.6.24总结一下,希望对大家有帮助:

1、定义:wait_queue_head_t my_queue;

2、初始化 init_waitqueue_head(&my_queue);

3、在一个函数里面等待:wait_event(queue, condition) ;(别在中断里面搞)

4、在另一个函数里面唤醒:wake_up(wait_queue_head_t *queue); (这个可以在中断调用,去唤醒别的进程,特别是dma操作类的)

有好几个等待和唤醒函数,大家可以慢慢试。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux内核的 等待队列 使用方法,wait_queue_head_t,进程休眠 的相关文章

  • 使用Boost获取成员函数的数量和参数类型? (升压::function_traits)

    对于普通的普通函数来说 它工作得很好 下面的代码工作得很好 它只打印应该的内容 int cdecl int char 2 int char include
  • 有什么方法可以从 cli 中找到 python 中函数的所有可能的 kwargs 吗?

    有没有办法从命令行发现 python 中函数的潜在关键字参数 无需查看源代码或文档 有时源是 c lib 即使不可见 您可以使用inspect模块 在 3 3 中 这很容易使用inspect signature https docs pyt
  • 如何在 python 中的不同终端窗口中运行函数/线程?

    我有一个这样的程序 from threading import Thread def foo1 arg print foo1 gt gt gt Something input foo1 gt gt gt Enter Something de
  • Bash 函数中的返回值

    我正在使用 bash 脚本 我想执行一个函数来打印返回值 function fun1 return 34 function fun2 local res fun1 echo res 当我执行时fun2 它不打印 34 为什么会这样呢 虽然
  • 切换 git 分支时如何处理 vim 缓冲区?

    因此 我在 vim 缓冲区中打开了大量文件 并且正在使用 git 处理功能分支 突然 我意识到我需要恢复到主分支来进行快速修复 提交后 我将 vim 会话保持打开状态并切换回 master 分支 但是 当我尝试从缓冲区加载我需要的文件时 我
  • 在 Golang Server 中接受持久的 tcp 连接

    我正在尝试使用 Go 并且想创建一个 TCP 服务器 我可以通过 telnet 访问该服务器 发送命令并接收响应 const CONN HOST localhost CONN PORT 3333 CONN TYPE tcp func mai
  • 如何避免使用全局变量?

    我使用全局变量 但我读到它们不是一个好的实践或Pythonic 我经常使用的函数会给出许多是 否变量 我需要在主函数中使用这些变量 例如 在不使用全局变量的情况下 如何编写以下代码 def secondary function global
  • 程序如何在Python中的两个函数之间进行选择?

    我有一个 Python 3 2 程序 可以计算未来任意时间段内的投资价值 它可以处理单利和复利 问题是我定义了两个函数 main 和 main2 第一个是简单函数 第二个是复利函数 现在我想做的是 根据用户的一些输入 程序在运行 main
  • 私有静态方法有必要吗?

    原理工程师 https stackoverflow com users 201787 metal在我上一家公司有一条规则private static方法应该作为实现文件中的函数实现 而不是作为类方法 我不记得他的规则是否有任何例外 我在目前
  • 在 C 或 C++ 中返回结构是否安全?

    我的理解是不应该这样做 但我相信我已经看到过这样做的示例 注意代码不一定在语法上正确 但想法就在那里 typedef struct int a b mystruct 然后这是一个函数 mystruct func int c int d my
  • Haskell 中函数和函子有什么区别?只有定义吗?

    在 Haskell 中 当编写函数时 这意味着我们将某个东西 输入 映射到另一个东西 输出 我尝试 LYAH 来理解 Functor 的定义 看起来和普通 Functor 一样 函数被称为函子有什么限制吗 Functor 是否允许有 I O
  • PHP 函数可以接受无限数量的参数吗? [复制]

    这个问题在这里已经有答案了 在 PHP 中有类似的函数unset 支持我们向它们抛出的任意数量的参数 我想创建一个类似的函数 它能够接受任意数量的参数并处理所有参数 任何想法 如何做到这一点 在 PHP 中 使用该函数func get ar
  • 在C中更改函数内的数组

    我正在学习 C 并且很困惑为什么在 main 中创建的数组不会在函数内部更改 我假设传递的数组是一个指针 并且更改指针应该更改数组 对吧 有人可以解释这种情况下发生了什么吗 谢谢你的帮助 int main int i length 10 i
  • 同一参数有两个不同的名称有什么意义?

    func mapEachElement inArray arr Int withFunc aFunc Int 为什么会有 inArray 然后 arr 有什么意义 对于 withFunc 和 aFunc 也是如此 它使代码变得更加复杂并且阅
  • 方案中的尾递归幂函数

    我在方案中编写尾递归幂函数时遇到问题 我想使用辅助函数来编写该函数 我知道我需要一个参数来保存累计值 但在那之后我就陷入了困境 我的代码如下 define pow tr a b define pow tr h result if b 0 r
  • PrintStream是有缓冲的,但是flush不会降低性能,而BufferedOutputStream会加速性能

    我预计由于 PrintStream 是缓冲的 通过在每次 print 之后添加刷新操作 速度性能应该会显着降低 但事实并非如此 如下面的代码片段所示 此外 将 PrintStream 包裹在 BufferedOutputStream 周围可
  • 如何获取调用函数的“this”值?

    如果我有一个这样的函数 function foo this console log this function bar bar prototype func function foo this var test new bar test f
  • 在 Python IDLE 会话中显示用户定义函数的列表

    是否可以在 IDLE 会话中显示所有用户功能的列表 我可以看到它们在自动完成中弹出 所以也许还有其他方法可以只显示为会话定义的用户功能 当您忘记函数名称时 它很有用 而且当您想确保在会话关闭时不会丢失函数的源代码时 这应该为您提供全局范围内
  • 如何将函数应用于多个 pandas 数据框

    我有多个数据框 df1 df2 df3 dfn 它们具有相同类型的数据 但来自无法连接的不同描述符组 现在我需要手动将相同的函数应用于每个数据帧 如何将相同的函数应用于多个数据框 pipe https pandas pydata org p
  • 在 JavaScript 中引用 C# 变量

    我已经阅读了很多线程 但我不明白为什么这不起作用 我正在创建一个将用作导航栏的 SharePoint Web 部件 一切都很顺利 直到我尝试在 JS 代码中引用 C 变量 这是来自 VisualWebPart1UserControl asc

随机推荐

  • Hacking The Box----Awkward

    信息收集 nmap扫描 发现22号端口和80号端口打开 80号端口上运行着http服务器 访问ip后URL变为hat valley htb 修改 etc hosts文件 添加10 10 11 185 hat valley htb 然后就能正
  • parseInt和Math.floor的区别

    引入 在大多数情况下 他们都可以用来取一个小数的整数部分 但是在某些特殊场景下 就只能使用math floor 比如我们想取一个区间范围内的值 如果使用 就可以取到 但如果使用 就只能取到 这是为什么呢 首先我们还是从他们的原理开始看 co
  • docker容器添加ssh服务

    本篇文章主要介绍如何为一个容器添加ssh服务 使得可以从另一台服务器直接ssh到一个容器内部 达到直接访问容器内部环境的目的 避免需从宿主机docker exec或attach进入容器 实验环境 两台服务器地址 192 168 91 131
  • 外卖项目 - Day01

    外卖 Day01 外卖项目介绍 开发环境搭建 后台登录功能开发 后台退出功能开发 1 项目介绍 在开发外卖这个项目之前 我们需要全方位的来介绍一下当前我们学习的这个项目 接下来 我们将从以下的五个方面 来介绍 外卖这个项目 1 1 项目介绍
  • linux ui 代码,Android自定义UI模板图文详解【附源代码】

    不知道大家在实际开发中有没有自定义过UI模板 今天花时间研究了一下Android中自定义UI模板 与大家分享一下 每个设计良好的App都是自定义标题栏 在自定义标题栏的过程中大部分人可能都是自定义一个标题的xml文件 然后在需要的地方直接通
  • c++ svd实例整理

    矩阵简单封装 下面两个是一样的 http download csdn net download o07sai 2206411 https github com jiaohaitao svd double数组 http download cs
  • Java引用传递问题

    if planSuccessServices contains value service put choose yes successServices add service if planFailServices contains va
  • 在Windows上实现link

    众所周知 在Linux上 link命令很好很强大 可以很方便的为我们创建链接 但是在Windows上却没有对应的功能 之多只能建一个快捷方式 但是远远达不到link的功能 如何才能使Windows上也具备类似Linux上link的功能呢 最
  • 【Spring Boot 源码学习】自动装配流程源码解析(上)

    Spring Boot 源码学习系列 自动装配流程源码解析 上 引言 往期内容 主要内容 1 自动配置开关 2 加载自动配置组件 3 自动配置组件去重 总结 引言 上篇博文 笔者带大家从整体上了解了AutoConfigurationImpo
  • el search模糊查询

    import json from elasticsearch import Elasticsearch es Elasticsearch 192 168 55 90 9200 source arr uri camera deviceId p
  • 如何用多种方式安装jupyter notebook

    目录 注意 安装python的方式 在官网下载python3 安装后需要确保安装Python成功 安装jupyter notebook的三种方式 1 使用终端安装jupyter notebook 2 使用Pycharm控制台安装jupyte
  • javafx+mysql实现学生信息管理系统(连接数据库实现增删改查功能)利用了SceneBuilder

    功能简单介绍 因为是重新学的 花了一天写出来的 界面比较简陋 暂时还没有完善 但是功能都可以正常实现 数据库建表 可以参考格式 可以根据需要对应修改tableview中的column 这个对表没有太多要求 可以自行修改 首先是登陆页面 账号
  • 如何用Python将普通视频变成动漫视频

    文章目录 容我废话一下 一 思路流程 二 图像转动漫 三 视频帧读取与视频帧写入 容我废话一下 最近几个月 毒教材被曝光引发争议 那些编写度教材的人着实可恶 咱程序员也没有手绘插画能力 但咱可以借助强大的深度学习模型将视频转动漫 所以今天的
  • CentOS入门

    1 CentOS 是RHEL的克隆版本 但其更新 如升级 漏洞修复等 要比RHEL慢一点 因其稳定 长期的升级支持 保守性以及大规模使用性能稳定等因素被企业普遍使用 RHEL发行方式有两种 一是发行二进制 二是发行源码 而CentOS就是将
  • Android Studio一课一得

    一 概述 Android Studio是由Google开发的官方集成开发环境 IDE 主要用于Android平台上应用程序 App 及游戏的开发 Android Studio提供了丰富的工具和功能 包括代码编辑器 可视化布局编辑器 调试器和
  • 无限重置IDEA试用期的小脚本

    1 Reset the trial period of IDEA vbs Set wsshell CreateObject WScript Shell Set filesys CreateObject Scripting FileSyste
  • 层次分析法小结

    层次分析法的步骤 建立层次结构模型 构造成对比较矩阵 层次单排序及其一次性检验 层次多排序及其一次性检验 1 建立层次结构模型 层次结构模型一般分为三个部分 目标层 也就是我们最终需要寻找出来的最佳结果 通常为一个 准测层 结果优劣的判断因
  • Spark读取外部数据的几种方式

    一 spark读取csv文件 四种方式 方式一 直接使用csv方法 val sales4 DataFrame spark read option header true option header false csv file D Soft
  • lu分解法解线性方程组 python_一篇文章入门大规模线性方程组求解

    前面介绍过主要的线性方程组求解库 参考附录 求解大规模线性方程组是仿真软件求解器的底层技术 求解器时间基本都消耗在方程组求解上 线性方程组的解法比较成熟 方法也有很多 而且不同的方法对应不同类型方程组 所以在方法选择上实际很讲究 商业软件通
  • linux内核的 等待队列 使用方法,wait_queue_head_t,进程休眠

    当你在用户空间需要读写一大片数据的时候 这个就用上了 以下来自 http www yuanma org data 2006 1207 article 1916 htm 假设我们在 kernel 里产生一个 buffer user 可以经由