| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> 系统运维 -> I/O复用 :select poll epoll -> 正文阅读 |
|
|
[系统运维]I/O复用 :select poll epoll |
I/O复用就是不用产生多个线程的情况下,处理多个客户端发来的数据I/O复用使得程序能同时监听多个文件描述符,提高程序性能使用情况:1.同时需要处理多个套接字?? 2.同时处理用户输入和网络连接? 3.同时处理监听套接字和连接套接字(用的最多)? 4.同时处理TCP、UDP请求? 5.同时监听多个端口,处理多种服务?? 等等 读事件:对描述符读的时候不会阻塞,会得到数据,只要不阻塞,读事件就绪的,接收缓冲区如果有数据可以读,读事件就绪的,发送缓冲区有空间,那么写事件就绪的sockfd:客户端connect连接服务器,有读事件产生 连接套接字:接收缓冲区中有数据有读事件,客户端关闭套接字有读事件 文件描述符就绪条件可读:1.socke套接字内核接收缓存区中字节数大于或等于低水位标记SO_PCVLOWAT(一般为1,也就是有数据就会有读事件),可以无阻塞读操作,且读操作返回字节数大于0 2.socket套接字同系的对方关闭连接时,此时socket套接字有读操作返回0 3.监听套接字上有新的来自客户端的连接时会有读操作 4.socket上有未处理的错误,此时使用getsockopt来读取清除该错误 可写:1.socket上有未处理的错误,此时使用getsockopt来读取清除该错误 2.socket内核发送缓存区中可用字节数大于或等于低水位标记SO_SNDLOWAT,此时可以无阻塞写操作,写操作返回值大于0 3.socket的写操作被关闭,对写操作被关闭的socket执行写操作将触发SIGPIPE信号 4.socket使用非阻塞connect()连接成功或失败后会返回错误信息 select将所有文件描述符存入一个集合,在将集合调入select()中,返回值为几就有几个数据就绪,-1返回失败,返回0超时,再将所有描述符遍历一遍,找到就绪描述符,处理数据 头文件 #include<sys/select.h> select(最大描述符加1,读集合,写集合,异常集合,超时时间结构体空就一直阻塞)
fd_set这个集合中,一个位表示一个文件描述符,一共1024个
FD_ZERO ( ) 清空整个集合
FD_SET ( ) 将集合中就描述符就绪对应的位置置为1
FD_ISSET ( )检测有没有被设置,按位与,看是否为真,为真说明就绪
poll:系统调用和select类似,都是在指定时间内比轮询一定数量的描述符,测试其中是否有就绪的描述符头文件 #include<poll.h> 创建结构体数组 struct pollfd fds[ ];
结构体数组初始化
?结构体数组中 revents成员是用来判断套接字里面的事件是否为读或者写等一些事件的
poll(结构体数组,数组元素个数,超时时间)
epoll :linux上一个特有的I/O服用函数,实现上和select、poll差异很大,它是由一组函数来完成任务,它把用户关心的文件描述符上的事件放在内核的事件表里,无须每次调用都重复传入描述符集合或事件集合,但它需要使用额外的文件描述符来唯一标识内核中的事件表头文件 #include<sys/epoll> 第一步 epoll_create( 告诉内核事件表的大小) //创建一个文件描述符来标识在内核中的事件表 返回的epfd是一个id ,通过epfd可以指定要访问的内核事件表里的事件
第二步 epoll_clt(? ) //操作内核事件表? 动态维护 EPOLL_CTL_ADD? //往内核事件表里面添加元素的
EPOLL_CTL_MOD? //修改内核事件表上的事件 EPOLL_CTL_DEL? //删除内核事件表的事件
第三步 epoll_wait () //等着内核事件表中就虚的描述符,返回就绪描述符的个数
epoll LT和ET模式LT(边缘触发) : 当客户端向接收缓冲区发数据,接收缓冲区中有数据,读事件就绪,recv读走一个后,I\O函数提醒还有数据,认为读事件依然就绪,会继续读,这种情况不会丢数据 ET(水平触发): 客户端发来数据接收缓冲区中有数据,读事件就绪,recv读走一个后没读完,哪怕缓冲区还有数据,I\O函数不会提醒,第二波数据发来时候,服务器才会第二次检测到读事件发生,这时候又读走一个,但是还没读完,所以说就是在客户端发数据的时候才有读事件就绪,服务器不管读了几个,只会读一次,并不会有读事件产生,只有客户端再次发送数据时才会有读事件产生,这就要求了 要一次性把数据读完,讲求高效率 |
|
|
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年12日历 | -2025/12/1 22:53:42- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |