int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*timeout);
struct fd_set 为一个集合 集合里存放的是文件描述符即文件句柄
都是一些宏:
清空集合FD_ZERO(fd_set *)
加入一个描述符到集合FD_SET(int ,fd_set*)
从集合删除一个描述符FD_CLR(int,fd_set*)
检查集合中的文件描述符是否可读写FD_ISSET(int ,fd_set* )
int maxfdp是一个整数值,
是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1
timeval*timeouts时间 NULL阻塞状态
select的特点:select 选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,
select需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。
select的复杂度很高O(n)
select支持的句柄数是有限制的, 同时只支持1024个,这个是句柄集合限制的,如果超过这个限制,
很可能导致溢出,而且非常不容易发现问题, TAF就出现过这个问题, 调试了n天,才发现:)
当然可以通过修改linux的socket内核调整这个参数
epoll的特点:epoll对于句柄事件的选择不是遍历的,是事件响应的,
就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高,内核将句柄用红黑树保存的。
struct fd_set 为一个集合 集合里存放的是文件描述符即文件句柄
都是一些宏:
清空集合FD_ZERO(fd_set *)
加入一个描述符到集合FD_SET(int ,fd_set*)
从集合删除一个描述符FD_CLR(int,fd_set*)
检查集合中的文件描述符是否可读写FD_ISSET(int ,fd_set* )
int maxfdp是一个整数值,
是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1
timeval*timeouts时间 NULL阻塞状态
select的特点:select 选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,
select需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。
select的复杂度很高O(n)
select支持的句柄数是有限制的, 同时只支持1024个,这个是句柄集合限制的,如果超过这个限制,
很可能导致溢出,而且非常不容易发现问题, TAF就出现过这个问题, 调试了n天,才发现:)
当然可以通过修改linux的socket内核调整这个参数
epoll的特点:epoll对于句柄事件的选择不是遍历的,是事件响应的,
就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高,内核将句柄用红黑树保存的。
(复杂度降低到了O(k),k为产生I/O事件的流的个数,也有认为O(1)的)
文章有借鉴--谢谢