i/o多路复用模型——select与epoll

i/o多路服复用模型———select与epoll

Selelct的作用:是一个系统调用(将用户空间切换到系统空间),由内核来监听select传递的文件描述符的集合,监听它们有无数据可读、可写、发是否发生异常,没有时一直阻塞,有发生变化就返回给用户空间来查询发生变化的通信描述符并做相应的处理读写等;

select函数原型:select(int maxfds, fd_set *readfds, fd_set *wreatefds, fd_set *execfds, const struct timeval *timeout);

第一个参数:文件描述符的范围, 比所监听的最大的文件描述符大1;

第二个参数:是一个文件描述符的集合(就是包含文件描述符的数组),用来被监控是否可读;

第三个参数:也是一个文件描述符的数组,他被用来监听这些文件描述符是否可写;

第四个参数:也是文件描述符的数组,用来监听这些文件描述符是否出现异常;

第五个参数:定时器结构体,可以用来设置阻塞的时间;若置为0,无论是否满足要求的文件描述符都讲将立刻返回;

若置为NULL, 则select将进入阻塞状态,阻塞进程,直到有文件描述符发生可读可写或异常;

若置为正整数,就是等待最长的时间;阻塞指定时间后立刻返回;

返回值:是发生可读可写或者异常的文件描述符的个数;若select函数出错,则返回一个小于零的数;

操作系统为我们提供4个宏函数,来对描述符集合进行操作;

void FD_SET(int fd, fd_set* fdset)

  将文件描述符fd,添加到数组fdset中;

void FD_CLR(int fd, fd_set *fdset);

  将文件描述符fd, 从数组里删除;

 

 

void FD_CLR(fd_set *fdset);

  将数组里面的文件描述符清空;

void FD_ISSET(int fd, fd_set *fdset);

做两件事情:1.先判断第一个参数fd,是否在第二个参数的数组里面;

2.然后判断这个fd是否发生变化

在调用select后使用FD_ISSET函数进行判断参数1的fd是否发生可读、可写、出错变化,有发生变化返回真,否则返回假;

 

select的缺点:1.   用户态与内核态频繁交互,当有上千万客户端连接时,拷贝通信描述 符到内核,系统开销很大,导致处理速度慢,性能下降;

  1. 使用数组存放通信描述符,导致延展性比较差;

 

优点:可移植性好,多个操作系统支持;

 

i/o多路复用的另一个强大的系统调用就是epoll;

  它解决了select的两个缺点:

1.解决了用户空间与内核空间交互频繁的问题,epoll是将存放通信描述符的集合储存在用户空间与内核空间的共享内存中,无需做数据拷贝;

2.epoll模型使用红黑树存放通信描述符,解决了数组需要规定数组大小,延展性很差的问题;

epoll具体操作参见大神整理的资料,同时感谢分享;

在此附上转载连接:    https://blog.csdn.net/yusiguyuan/article/details/15027821

                                        https://blog.csdn.net/ljx0305/article/details/4065058

 

你可能感兴趣的:(liunx系统编程)