10_4阻塞和非阻塞跟poll和等待队列

阻塞和非阻塞

广泛上的区别就是 应用程序如果非阻塞那读取不到数据就应该马上有返回值
阻塞的话就是在应用程序去read数据,但是设备驱动没有数据,就一直卡住,直到有数据再继续往下

补充阻塞知识,应用层大部分都是阻塞
如果要非阻塞 ,应用程序在打开设备节点的时候填写int fd = open(“/dev/key0”, O_RDWR|O_NONBLOCK);,这里指定了
希望对这个节点后续的操作都是非阻塞
此时会把这个标志位传到驱动层,驱动层应该根据上面的标志位,使用正确的方法来返回值
所以read时候阻塞还是非阻塞取决于驱动的实现了

等待队列

等待队列是进程打开这个文件指定了阻塞,应用程序调用read()
read的时候因为没有数据,驱动把这个进程放入等待队列
驱动初始化应该建立一个等待队列列表,每个访问设备的进程都是一个队列项
设备不可用的时候就要将这些进程对应的等待队列项添加到等待队列里面
添加到等待队列头中以后进程才能进入休眠态

最后中断产生了数据,使用void wake_up_interruptible() 唤醒队列
队列中所有存的进程继续之前休眠前的代码

poll

可以理解poll对应的就是非阻塞了
应用程序,可以打开多个设备,使用poll进行查询数据,如果有数据
再调用read(),主打一个调用read()马上有结果
所以poll算是一个监听者

注意的点,关于休眠

阻塞是应用程序调用驱动的read,驱动发现没有数据返回给read
那驱动使用 wait_event_interruptible(key_dev->wq_head, key_dev->have_data);
上面这个函数相当于 下面三个函数
__set_current_state(TASK_INTERRUPTIBLE); //设置当前进程为休眠可中断
add_wait_queue(wait_queue_head p,wait_queue_t wait);//但是要把这个进程的信息放入等待队列中
schedule();//开始调度

而在poll中,调用到驱动的poll
执行 poll_wait(filp, &key_dev->wq_head, pts); 只是为了把当前进入放入等待队列中,不会触发休眠
休眠时第一次执行完驱动poll后,回到VFS层,vfs层帮进程休眠的
问:为啥poll还有个等待队列?
答:上面vfs层帮你休眠了,那数据来了,我怎么让你这个进程醒过来,还是得唤醒等待队列啊
在这里插入图片描述

poll的流程

在这里插入图片描述
第一步需要初始化并且创建一个等待队列,放在驱动中

第二步: app打开一些文件节点,现在这些文件节点就是我们要用poll监控的节点,
把需要监控的数据内容(POLL_IN,POLL_OUT)等和节点组成数组pds[]

应用先 poll(pfds, 2, 5000); //5s没有数据就超时 加pfds表

第三步
应用程序在while中调用poll
系统调用 ->内核的vfs poll ->驱动poll

第四步:
触发了软中断,调到vfs层,这里vfs贴心的提供了一个for循环,会第一次调用到驱动的中的poll

第五步:

到驱动层
此时调用了 poll_wait(filp, &key_dev->wq_head, pts);
把驱动中注册的等待队列头,和pts poll的一个表格进行关联,这时候等待队列中就存放了当前的进程了
假设不放入队列里,那以后发生中断时,中断服务程序去哪里找到你嘛?
注意此时还没有休眠,还得继续往走回到VFS层的

第6步:
此时自己的驱动程序返回为0,说明这个时候没有数据,回到VFS层
开始休眠

从现在开始分成两种情况
1:休眠超时情况,刚刚传入到vfs层中说应用程序只等待5s
那5s到了,在vfs层中的for循环开始新的一轮,又回到了第四步

此时是第二次进入
因为这个进程放进去过一次等待队列了,这次就不继续放了
此时还是没有数据,需要返回了

返回给应用层,没有数据,应用层继续往下执行把

第二种情况有中断产生,能返回数据
第7步,中断发生,中断里有函数wake_up_interrupt(wq_head)
这时候所有在 等待队列里的进程都被唤醒,继续往下执行

回到第4步骤,图中的黄色部分,因为被中断唤醒,进程继承从这个地方执行
再次回到for循环

进入第五步
再次调用到驱动中的poll,这时候检测到右数据,那么驱动poll,会返回POLL_IN这些掩码
传输到VFS层再到应用层

最后到第8步
再次调用到驱动中的poll,这时候检测到右数据,那么驱动poll,会返回POLL_IN这些掩码
传输到VFS层再到应用层,应用层的poll返回了有数据,根据返回值判断是哪个驱动有数据,并且是什么数据
应用层继续调用read读取数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/123679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

辅助驾驶功能开发-功能规范篇(22)-4-L2级辅助驾驶方案功能规范

1.3.4 LDW系统功能定义 1.3.4.1 状态机 1.3.4.2 功能定义 1.3.4.2.1 信号需求列表 1.3.4.2.2 系统开启关闭 1)初始化 车辆上电后,车道偏离预警系统(LDW)进行初始化,控制器需要在上电后 220ms 内发出第一帧报文,并在 3s 内 完成内部自检,同时上电 3s 内不进行关联系统…

ActiveMQ

ActiveMQ 安装 下载网址:ActiveMQ 一定要和自己安装的jdk版本匹配,不然会报错 下载到本地之后解压缩 有可能端口号被占用 解除端口号占用,参考:Windows_端口被占用 打开cmd 查询所有的端口号 netstat -nao查询指定端口号 n…

数组元素逆序交换

数组元素逆序交换 例如&#xff1a; 输入&#xff1a; 1,2,3,4,5 输出&#xff1a; 5,4,3,2,1 代码&#xff1a; #include<stdio.h> #define N 5 int main() {int a[N], i, temp;for (i 0; i < N; i) {scanf("%d", &a[i]);}for (i 0; i < N…

C语言选择排序

1.选择排序(Selection sort) 选择排序是简单直观的排序算法。 基本思想&#xff1a;从首元素开始&#xff0c;首元素与它后面的所有元素进行比较&#xff0c;找到数列中最小的元素&#xff0c;与首元素值交换。然后下一个元素与它后面的元素比较&#xff0c;得到第二小的元素…

对Linux线程的理解(什么是线程,线程的创建终止等待分离,线程互斥,Linux常见的锁,线程同步),两万字总结,有这一篇文章就够了!

文章目录 一、什么是线程1.线程是怎样描述的2.线程与进程的区别3.线程的优缺点4.理解Linux的轻量级进程 二、Linux线程控制1.线程创建:pthread_create()2.线程终止:pthread_exit()3.线程等待:pthread_join()4.分离线程:pthread_detach() 三、Linux线程互斥1.互斥量2.线程安全与…

我在Vscode学OpenCV 初步接触

OpenCV是一个开源的计算机视觉库&#xff0c;可以处理图像和视频数据。它包含了超过2500个优化过的算法&#xff0c;用于对图像和视频进行处理&#xff0c;包括目标识别、面部识别、运动跟踪、立体视觉等。OpenCV支持多种编程语言&#xff0c;包括C、Python、Java等&#xff0c…

在HTML当中引入Vue控件,以element-ui为例

前情&#xff1a;需要实现一个同时满足按天、按周、按月选择的时间选择器&#xff0c;但是以HTML为基础写的都不太满足我的要求&#xff0c;要么只能按天选择&#xff0c;要么就是想选择久远的时间得点很久&#xff0c;除非自己写捷径&#xff0c;所以就看上了element-ui的这个…

动静分离技术

一、HAproxy 动静分离 1、概念&#xff1a; HAproxy 动静分离技术是一种用于优化 Web 服务器性能和提高用户体验的策略&#xff0c;它通过将动态内容和静态内容分别路由到不同的后端服务器来实现&#xff0c;减轻服务器负载&#xff0c;提高网站的响应速度。 动态内容包括由…

SylixOS BSP开发(七)

实现系统调试信息打印接口 当系统出错时或者使用内核日志时会输出一些打印信息&#xff0c;这最终都是调用到bspLib.c中的bspDebugMsg 这个接口来实现的&#xff0c;所以我们在开发BSP时&#xff0c;第一个要做的工作就是实现这个接口。 一般的调试信息都是通过串口来输出的&am…

经典目标检测神经网络 - RCNN、SSD、YOLO

文章目录 1. 目标检测算法分类2. 区域卷积神经网络2.1 R-CNN2.2 Fast R-CNN2.3 Faster R-CNN2.4 Mask R-CNN2.5 速度和精度比较 3. 单发多框检测&#xff08;SSD&#xff09;4. YOLO 1. 目标检测算法分类 目标检测算法主要分两类&#xff1a;One-Stage与Two-Stage。One-Stage与…

虚拟机Ubuntu下运行vue-element-admin项目

一.环境搭建 1.安装nodejs sudo apt install nodejs 安装完成后&#xff0c;查看对应的版本号 nodejs -v没有问题&#xff0c;会输出对应版本号&#xff0c;我这里是10.19.0 v10.19.0 2.安装npm sudo apt install npm安装完成查看对应的版本号&#xff0c;确认OK npm -…

linux中nginx配置https

一、版本适配 版本一定要适配&#xff0c;否则会报错各种参数定位不到不识别的错误&#xff0c;以下是版本适配信息&#xff0c;各位观客自行按照以下信息匹配版本。 Nginx 1.11.5及以上版本与OpenSSL 1.0.2及以上版本兼容。Nginx 1.15.2及以上版本与OpenSSL 1.1.1及以上版本兼…

JavaScript_Pig Game保存当前分数

上个文章我们基本上完成了摇色子和切换当前玩家的功能。 现在我们开始写用户选择不再摇骰子的话&#xff0c;我们将用户的当前分数存入到持有分数中&#xff01; ● 首先我们应该利用一个数组去存储两个用户的分数 const scores [0, 0];● 接着我们利用数组来对分数进行累…

用户登录前后端开发(一个简单完整的小项目)——SpringBoot与session验证(带前后端源码)全方位全流程超详细教程

&#x1f9f8;注&#xff1a;不要看我的文件多&#xff0c;那是我的其他项目&#xff0c;这个项目所用的文件我会全部用红框框起来&#xff0c;没框的部分不用管&#xff0c;前端两个文件&#xff0c;后端一个文件 &#x1f4dc; 目录 首先&#xff0c;定义前后端交互接口 然…

Oracle (7)Online Redo Log Files

目录 一、Oracle Online Redo Log Files及其相关内容介绍 1、Online Redo Log Files简介 2、Online Redo Log Files特点 3、Online Redo Log Files文件组 4、多路复用文件 5、联机重做日志文件工作方式 6、LGWR什么时候写重做 7、LS和LSN 8、删除Redo文件成员 9、删除…

ZYNQ连载07-PIN设备

ZYNQ连载07-PIN设备 1. 简述 RT-Thread PIN设备 这里参看RT-Thread提供的PIN设备管理接口&#xff0c;简单封装了几个接口函数。 2. 实现 #include "include/drv_gpio.h" #define LOG_TAG "drv_gpio" static XGpioPs xgpiops;void rt_pin_mode(rt_…

目标检测算法改进系列之嵌入Deformable ConvNets v2 (DCNv2)

Deformable ConvNets v2 简介&#xff1a;由于构造卷积神经网络所用的模块中几何结构是固定的&#xff0c;其几何变换建模的能力本质上是有限的。在DCN v1中引入了两种新的模块来提高卷积神经网络对变换的建模能力&#xff0c;即可变形卷积 (deformable convolution) 和可变形…

JVM虚拟机:从结构到指令让你对栈有足够的认识

本文重点 在前面的课程中,我们学习了运行时数据区的大概情况,从本文开始,我们将对一些组件进行详细的介绍,本文我们将学习栈。栈内存主管java的运行,是在线程创建时创建的,它是线程私有的,它的生命周期是跟随线程的生命期,也就是说线程结束栈内存就释放了,对于栈来说…

HarmonyOS鸿蒙原生应用开发设计- 图标库

HarmonyOS设计文档中&#xff0c;为大家提供了独特的图标库&#xff0c;开发者可以根据需要直接引用。 图标库可以分为双色图标、填充图标、线性图标。具体分为 键盘、箭头、连接状态、媒体、人、设备、索引、通信、文件、物体与工具等。 整体分类 开发者直接使用官方提供的图标…

【影刀演示_发送邮件的格式化HTML留存】

发送邮件的格式化HTML留存 纯文本&#xff1a; 亲爱的小张: 端午节将至&#xff0c;公司为了感谢大家一年以来的辛勤工作和付出&#xff0c;特别为大家准备了京客隆超市福利卡&#xff0c;希望为大家带来些许便利和节日的喜悦。 以下是您的福利卡卡号和密码&#xff0c;请您…