一、I/O复用的含义:
是一种计算机对于I/O事件的处理,事实上,在I/O上不可能时时刻刻都有事件发生(传输数据),所以就把事件监听起来,当有事件发生,再分配进程或线程去处理它,而不是让一个进、线程阻塞在这里,等待事件发生。
二、I/O分为
1、同步I/O :
数据的读写由应用程序自己完成,由内核来向应用程序通知就绪事件。
2、异步I/O:
数据的读写由内核完成,内核向应用程序通知完成事件。
三、select poll epoll
select
1.函数原型和返回值
Int select(int nfds,struct fd_set * readfds ,struct fd_set* writefds,struct fd_set *exceptfds ,struct timeval * timeout)
返回值: -1 出错 0 超时 >0 就绪的文件描述符的个数
2.各参数以及含义
readfds 可读事件
writefds 可写事件
exceptfds 异常事件
Nfds :最大文件描述符的值加一 提高底层实现效率
Timeout :定时器 超时时间 NULL 永久阻塞 直到有文件描述符上有事件发生
3.fd_set结构体定义 以及如何将文件描述符分别设置到 readfds writefds exceptfds
fd_set 记录文件描述符 int fds[32] 按位表示关注的文件描述符
如何设置:
FD_ZERO(fd_set*set); 清空fdset的所有位
FD_SET(int fd,fd_set * set); 设置fdset的位fd
FD_CLR(int fd, fd_set * set); 清除fdset的位fd
4.如何返回就绪文件描述符
Select返回后,如何知道那些文件描述符就绪
内核仅仅将在fd_set结构体变量中将就绪文件描述符的位修改
1(未就绪) -> 0(就绪)
FD_ISSET(int fd, fd_set * fdset);测试fdset的位上是否有事件发生(是否被修改)
5.应用程序如何探测就绪的文件描述符
循环 FD_ISSET()
6.Select 启动监听,每次select调用之前都会重置readfds,writefds exceptfds 。 Select每次都会将所有的文件描述符返回,select返回后还必须探测具体哪些是就绪的文件描述符 o(n)
不但需要它往内核传递关注的文件描述符,也需要返回就绪的文件描述符,将就绪的和未就绪的都返回。
1)记录每种事件的结构 在数组中按位来记录关注的文件描述符上的事件
2)每次最多监听1024个文件描述符,最大值1023
3)Select函数返回时,通过传递的结构体变量将结果带回,(就绪的文件描述符,未就绪的)并且内核修改用户变量
3.1) 每次都必须循环探测那些文件描述符就绪(o(n))
3.2)每次调用都必须重新设置三个结构体变量
4.select函数的第一个参数 最大的文件描述符值加一 提高(内核)底层效率