特点:多个IO复用一个进程,不创建新进程和线程,效率高(不适合处理比较耗时的任务)
1.select:
1.int select(int nfd,fd_set *readfds,fd_set *writefds,fd_set *exceptfds,struct timeval *timeout);
参数:关注的文件描述符最大值+1;读事件的文件描述符集合,写事件的文件描述符集合,其他异常;超时时间
void FD_CLR(int fd,fd_set *set);
void FD_ISSET(int fd,fd_ser *set); (返回值结果判断标志位是否被置起)
void FD_SET(int fd,fd_set *set);(添加文件描述符到集合中);
void FD_ZERO(fd_set *set);(清空集合)
成功返回到达集合的个数,失败返回-1;超时返回0;
步骤:1.创建文件描述符集合:fd_set;
2.添加文件描述符到集合中:FD_SET;
3.通知内核开始检测:FD_ISSET;
4.根据返回值进行相应操作
2.epoll:
1.int epoll_create(int size) 创建文件描述符集合
参数:关注的文件描述符集合
返回值:文件描述符集合句柄
2.int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event) 添加文件描述符到集合
参数:集合句柄;功能标志符(ADD添加,DEL删除,MOD修改);所要操作文件描述符;结构体(EPOLLIN读,EPOLLOUT写);
3.int epoll_wait(int epfd,struct epoll_event*events,int maxevents,int timeout)
成功返回到达事件个数,失败返回-1;超时返回0
3.select、poll、epoll区别:
1.select数量不足:
1.监测最大个数为1024;时间复杂度为O(n);
2.监听文件描述符集合在用户层,需要应用层和内核层互相传递数据;
3.需要循环遍历才能找到产生事件
4.只能工作在水平触发模式(低速),不能工作在边沿触发模式(高速模式)
2.poll不足:
1.文件描述符无个数限制,时间复杂度O(n);
2.其他三点与select相同
3.epoll:
1.创建内核事件表,不受到文件描述符上限限制,一对多,时间复杂度O(log n)
2.监听 事件表在内核中,效率高;
3.会直接获得产实事件的文件描述符信息,而不需要遍历监测
4.低速与高速均能触发
4.应用场景:
1.构建并发服务器
2.监测多个IO所对应通信(网络、串口、can...)
3.在阻塞IO中,进行超时监测