16.poll机制

news/2024/12/28 13:16:26/

POLL机制

poll机制的底层实现原理:基于等待队列来实现。

poll()函数,poll()函数底层函数接口有一个对应的函数指针。当调用poll()函数的时候,会找到对应的file_operations的成员变量poll,最终会调用poll成员变量指向的函数指针。

同步阻塞IO和异步阻塞IO

同步阻塞IO

应用层调用一个 read / write 对一个文件进行读写操作时, read / write可能使当前的进程或线程进入一个休眠态(进程 / 线程阻塞在一个文件的读写操作上),陷入休眠态的进程 / 线程只能通过对应的文件设备驱动唤醒自己。

异步阻塞IO

在应用层调用poll()函数时,poll()函数会对多个文件进行轮询操作,去查看每一个文件是否有特定的事件。若所有文件都没有发生特定的事件,那么poll()函数会阻塞当前进程 / 线程。

poll()函数文件操作涉及多个文件的轮询,所以poll()函数引起的进程 / 线程休眠,可以会被多个设备驱动唤醒。

多个文件对应多个设备驱动。阻塞在多个文件的轮询操作上(poll),可以被多个设备驱动唤醒。

文件I/O事件类型

事件类型:可读、可写、异常...

poll()函数的目的是查询每个文件的I/O事件,没查到就会引起休眠。这些事件是由设备驱动产生,产生后会唤醒由poll()函数导致的进程 / 线程休眠,poll()函数也能把发生的事件返回给用户空间。

poll()函数

头文件

#include <poll.h>

函数定义

/** 监视多个文件描述符的指定事件(注意:不是所有事件)* 事件发生时(设备驱动唤醒poll函数导致休眠的进程/线程),把发生的具体事件通知给用户程序* fds:数组类型详见下* nfds:pollfd数组的元素个数,要监控的文件描述符数量* timeout:超时时间(ms),不希望进程线程一直休眠在poll函数里*/
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
/** 返回值:*    成功:发生事件的文件数量,超时返回0*    失败:-1*/struct pollfd
{int fd;        // 要监视的文件描述符short events;  // 指定要监视的请求事件类型,通过设置一系列的宏来描述  	short revents; // 返回的事件类型,内核设置具体的返回事件,记录实际发生的事件
};

events监视的事件:

        POLLIN:系统内核通知应用层指定数据已经准备好,读数据不会被阻塞

        POLLPRI:有紧急的数据需要被读取

        POLLOUT:系统内核通知应用层IO缓冲区已经准备好,写数据不会被阻塞

        POLLERR:指定的文件描述符发生错误,必须先解决错误才能对文件做其他的处理

        POLLNVAL:无效的请求

        ...

实验环节

app.c文件

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <poll.h> int main(int argc, char *argv[])
{struct pollfd fds = {0};fds.fd = 0;	//标准输入fds.events = POLLIN;int ret = poll(&fds, 1, 5000);	//监视1个数组,5s超时if(ret == -1){printf("poll error!\n");}else if(ret){printf("data is ready!\n");}else if(ret == 0){printf("time out!\n");}return 0;
}

执行过程

gcc app.c -o App

sudo ./App(回车等待5s)

sudo ./App &

cat

2


http://www.ppmy.cn/news/1075211.html

相关文章

Android JNI系列详解之生成指定CPU的库文件

一、前提 这次主要了解Android的cpu架构类型&#xff0c;以及在使用CMake工具的时候&#xff0c;如何指定生成哪种类型的库文件。 如上图所示&#xff0c;是我们之前使用CMake工具默认生成的四种cpu架构的动态库文件&#xff1a;arm64-v8a、armeabi-v7a、x86、x86_64&#xff0…

[c++] 指定精度格式化

1.整数指定格式 格式“%03d” &#xff0c;如何把其中的03能够指定0-9之间的任何一个数呢&#xff1f; 方法1&#xff1a; 把“%03d”逐个字符进行展开&#xff0c;%03d --%% 0 %d d 然后整体当作格式使用&#xff0c; 举例: int aa 2;int nDotNum 3;CString ss1;CStr…

Redis之管道解读

目录 基本介绍 使用例子 管道对比 管道与原生批量命令对比 管道与事务对比 使用pipeline注意事项 基准测试 基本介绍 Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务器。 这意味着请求通常按如下步骤处理&#xff1a; 客户端发送一个请求到服务器&am…

CTFhub--文件上传--%00截断

首先查看网页源代码 允许上传文件格式 白名单 jpg png gif 用哥斯拉生成一木马文件&#xff0c;名字为 1.jpg 上传 用burp 抓包 在 “upload/” 后门添加 1.php%00 提交 用蚁剑连接 ctfhub{4fea5ea72c40690444354890}

获得硬盘ID(序列号、机器码)的C++代码源码

本篇文章属于《518抽奖软件开发日志》系列文章的一部分。 我在开发《518抽奖软件》&#xff08;www.518cj.net&#xff09;的时候&#xff0c;在软件的注册部分&#xff0c;需要获得硬盘的序列号(ID/机器码)。在网上找了一些代码&#xff0c;很多不好用&#xff0c;最后选了下面…

Kotlin,解决调用了函数但是函数体内没有执行的问题,什么时候使用invoke

fun main() {listOf(1,2,3).forEach{ foo(it)} } fun foo(a:Int) {print(a) }这段代码按照代码逻辑来说打印的是 123 但是没有这个打印 把foo函数转成java的代码如下 JvmStaticNotNullpublic static final Function0 foo(final int var0) {return (Function0)(new Function0 ()…

Java如何随机获取List中的元素?实现代码一次搞定!

推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 AI绘画 stable diffusion Midjourney 官方GPT文档 AIGC百科全书资料收集 史上最全文档AI绘画stablediffus…

高频面试题:如何分别用三种姿势实现三个线程交替打印0到100

最近面试遇到的一道题&#xff0c;需要三个线程交替打印0-100&#xff0c;当时对多线程并不是很熟悉因此没怎么写出来&#xff0c;网上搜了之后得到现 synchronized wait/notifyAll 实现思路&#xff1a;判断当前打印数字和线程数的取余&#xff0c;不等于当前线程则处于等待…