IO多路复用:select,poll,epoll

本文介绍了I/O多路复用技术中的select、poll和epoll三种方法,详细讲解了它们的工作原理和使用场景。select用于管理有限数量的文件描述符,poll通过链表结构解决了描述符数量的限制,而epoll提供了更高效和灵活的I/O事件管理,支持水平触发和边缘触发两种模式。epoll_ctl和epoll_wait是epoll的核心函数,允许动态添加和删除文件描述符,并能高效地检测就绪事件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

select使用

fd_set是一个long类型的数组,主要是作用与sokcet的句柄进行绑定

// 这里的fd 实际使用都是以 句柄 传入
FD_ZERO(fd_set *fdset);              // 将set清零使集合中不含任何fd
FD_SET(int fd, fd_set *fdset);       // 将fd加入set集合
FD_CLR(int fd, fd_set *fdset);       // 将fd从set集合中清除
FD_ISSET(int fd, fd_set *fdset);     // 检测fd是否在set集合中,不在则返回0

int select(int maxfds,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

maxfds:所有传入描述符的最大值加1

readfds:可读事件描述符的集合,返回的是可读事件的fd的集合,当一个fd收到数据时,代表其为可读的fd

writefds:可写事件描述符的集合,当一个fd可以发送数据时,其sendbuf不会满的,就会返回其可写事件。

timeout:为等待时间,select是个阻塞的IO,当传入-1时说明一直要等待,当传入大于0的时间,比如5s;select等待5s之后就会返回,不管其中是否可获取到就绪好的fd

readfds---->fd1fd2fd3...
writefds----->fd1fd2fd3...
errorfds------>fd1fd2fd3...

FD_ISSET():函数判断相应的集合是否准备就绪,比如readfs集合中,如果fd=5,但是没有收到数据,FD_ISSET(5,readfds)就为0。

poll:

poll与select类型,但是可以克服select的一个缺点,select是一个数组与fd进行相关联,但一个fd_set的长度是有限的;poll则使用链表去与fd相关联,理论上可以无限的。

pollfd:里面保存是fd与相应的事件(POLLIN,POLLOUT,POLLERR)代表着相应的读,写,错误事件

POLL(pollfd pollfds,int maxfd+1,struct timeval *timeout);

EPOLL:

主要的三个函数

1:int epoll_create(int size);  
2:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);  
3:int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);  

epoll_create:创建一个epoll的句柄

epoll_ctl:注册fd等待的事件,epfd就是epoll_create返回的句柄,op为操作:epoll_add,epoll_delte,添加,删除相应的fd事件,fd为注册的fd,*event是保存其相应的注册事件epollin,epollout,读与写等事件

epoll_wait:则是阻塞监听 epoll 实例上所有的 fd 的 I/O 事件,它接收一个用户空间上的一块内存地址 (events 数组),kernel 会在有 I/O 事件发生的时候把文件描述符列表复制到这块内存地址上,然后 epoll_wait 解除阻塞并返回,最后用户空间上的程序就可以对相应的 fd 进行读写了。

epoll两种触发模式

LT(水平触发)是默认的模式,ET(边缘触发)是“高速”模式。

LT:代表着只要有数据就会一直触发,比如recvbuf中有数据存在就会一直触发,直到resv中没有数据存在

ET:代表着只会触发一直, 比如recv接受数据时,只是数据到来的时候,触发一次,下次发送数据时再触发一次。不管recvbuf中是否还存在数据,如果服务器每次接受的数据都客户端小于发送的,那么下次再发送时,进行触发;服务器就会接着上次recvbuf的位置进行读取。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值