I/O复用:select
I/O复用:一个进程或者一个线程能够同时对多个文件描述符(socket)提供服务
服务器上的进程或者线程如何将多个文件描述符统一监听,当任意一个文件描述符上有时间发生,其都能及时处理。
Linux提供了三种I/O复用:
1.select
2.poll
3.epoll (Linux独有的)
单进程单线程同时处理多个文件描述符:select
select函数原型:
int select(int nfds, struct fd_set * readfds, struct fd_set * writefds, fd_set * exceptfds, struct timeval *timeout);
int nfds:所监听的最大的文件描述符的值 + 1;//提高底层实现效率
readfds,writefds,exceptfds:分别传递用户关注的可读、可写、异常事件的文件描述符。
timeout:设置超时时间;如果timeout为NULL,则select移一直阻塞。
如果返回值>0,返回就绪文件描述符的个数
如果返回值= =0,超时
如果返回值= =-1, 出错
select使用时要注意的点:
①.如何将文件描述符分别设置到readfds writefds excefds上去?
②.如何select返回后如何知道哪些文件描述符就绪?
因此我们要了解fd_set结构体:如下
fd_set其实就是个整型数组,固定了32个元素
即为该结构体:如果每一个元素32位,4字节表示一个文件描述符(一般不会太大),最多表示32个,太浪费。
①因此,采用按位操作将文件描述符分别设置到readfds writefds excefds上去,系统提供一系列操作函数:
②与此同时,select返回可以通过FD_ISSET知道哪些文件描述符就绪
还要注意:
每次调用select之前都必须重新设置readfds; writefds; exceptfds。
select每次都会将所有的文件描述符返回。
select返回后还必须循环探测具体哪些是就绪的文件描述符。O(n)