【Linux】14.IO多路转接之详解poll
2022/2/22 7:26:57
本文主要是介绍【Linux】14.IO多路转接之详解poll,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录
- poll:地位不如select,因为select可以跨平台,性能又不如epoll
- 接口函数
- poll的优缺点
- poll阻塞监控代码
- poll非阻塞监控代码
- poll超时时间监控代码
poll:地位不如select,因为select可以跨平台,性能又不如epoll
接口函数
int poll(struct pollfd* fds, nfds_t nfds, int timeout);
fds:事件结构数组,poll函数是通过用户传入的事件结构数组进行监控的,也是轮询监控的方式
如果要监控一个文件描述符,则组织一个事件结构,传递给poll
如果要监控多个文件描述符,则组织多个事件结构,放到数组当中,传递给poll
时间结构:struct pollfd{…}
struct pollfd { int fd; short events; short revents; }
fd:待要监控的文件描述符
events:关心当中文件描述符产生什么事件(可读、可写、异常)
POLLIN:可读事件
POLLOUT:可写事件
如果既关心可读事件也关心可写时间,则将POLLIN | POLLOUT
revents:在poll监控文件描述符的时候,真实产生的事件
poll在监控的过程当中,文件描述符发生了什么事件,就将该事件放到revents当中
在定义pollfd事件结构体的时候,不需要用户进行初始化,由poll函数进行初始化
小结:
(1)poll函数引入了事件结构数组的方式,对需要内核监控的文件描述符个数是没有限制了。
(2)poll在监控事件结构数组的时候,也是采用轮询遍历的方式进行监控,随着监控的事件结构(文件描述符)的增多,监控轮询效率下降。
(3)用户如果关心一个文件描述符的多种事件(可读、可写、异常),可以直接在同一个事件结构的结构体当中表示,不需要像select一样,添加到不同的事件集合当中去。
nfds:事件结构数组当中有效元素的个数,用来指导poll函数,轮询遍历的范围
eg:struct pollfd arr[10];
arr[0].fd = 0;
arr[0].events = POLLIN;
则:nfds = 1;
timeout:超时时间
> 0 :带有超时时间的监控,单位:毫秒
0 :非阻塞的监控方式
< 0 :阻塞监控的方式
注意区分poll与select的超时时间的传参方式
select的超时时间参数是struct timeval * timeout,需要传入timeval结构体地址。
poll的超时时间参数是int timeout,只需要传入数字即可。
返回值:> 0 :监控成功,返回就绪的文件描述符个数
== 0 :监控超时
< 0 :监控出错
poll的优缺点
优点:
(1)引入了事件结构的方式,用户不需要将关心的事件添加到不同的事件集合当中去。
(2)引用了事件结构的方式,对监控的文件描述符的个数不再限制。
(3)针对和select对比之后,当一次监控成功之后,下一次再次进行监控的时候,不需要重新添加。
缺点:
(1)与select一样也是采用轮询遍历的策略,随着监控的文件描述符增多,轮询效率会下降。
(2)poll不支持跨平台,只能在linux操作系统下使用
(3)在调用poll函数的时候,会将用户组织的事件结构数组,拷贝到内核空间,监控成功之后,会将事件结构数组从内核空间拷贝到用户空间,这个举动比较耗费性能。
poll阻塞监控代码
#include <stdio.h> #include <unistd.h> #include <poll.h> //阻塞 监控 0 号文件描述符 int main() { struct pollfd pf; pf.fd = 0; pf.events = POLLIN; // 关心可读事件 poll(&pf, 1, -1); // <0 是阻塞监控 char buf[1024] = {0}; read(0, buf, sizeof(buf) - 1); printf("buf is : %s\n", buf); return 0; }
poll非阻塞监控代码
#include <stdio.h> #include <unistd.h> #include <poll.h> //非阻塞监控 0 号文件描述符 int main() { struct pollfd pf; pf.fd = 0; pf.events = POLLIN; while(1) { int ret = poll(&pf, 1, 0); //0表示非阻塞 if(ret < 0) { perror("poll"); return 0; } else if(ret == 0) { printf("poll timeout\n"); sleep(1); continue; //超时,继续监控 } char buf[1024] = {0}; read(0, buf, sizeof(buf) - 1); printf("buf is : %s\n", buf); } return 0; }
poll超时时间监控代码
#include <stdio.h> #include <unistd.h> #include <poll.h> //超时时间监控0号文件描述符 int main() { struct pollfd pf; pf.fd = 0; pf.events = POLLIN; while(1) { int ret = poll(&pf, 1, 1); if(ret < 0) { perror("poll"); return 0; } else if(ret == 0) { printf("poll timeout\n"); sleep(1); continue; } char buf[1024] = {0}; read(0, buf, sizeof(buf) - 1); printf("buf is :%s\n", buf); } return 0; }
这篇关于【Linux】14.IO多路转接之详解poll的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法