一.什么是I/O复用?
假设我们拥有1000个线程进行读写操作,但是我们大部分时间都耗费在等待的时间上,同时1000个线程对资源占用和CPU的开销很大,因此使用一个线程来监控1000个读写操作符的状态,当其中某一个描述符状态就绪时,用一个线程去处理已经就绪的状态,这样对资源占用和CPU的开销就会十分少了。
I/O多路复用:多路网络连接复用一个IO线程。同时需要指出I/O复用虽然可以监听多个文件描述符,但它本身是阻塞的。且当多个文件描述符同时就绪,如果不采取额外措施,程序只能按顺序依次执行,这使得服务器程序看起来是串行工作的,如果想要实现并发只能采用多线程编程。
从上图可以看出通过一个线程对IO流的状态监控,来实现同时管理多个线程。
二.select、poll、epoll详解
1.select
#include<sys/select.h>
#include<sys/time.h>
int select(int maxfdp1, fd_set *readset, fd_set *writest, fd_set *exceptest, const struct timeval *timeout);
//返回:若有就绪描述符,则返回值为其数目,若超时则为0,出错则为-1并设置errno。
//如果select在等待期间程序接收到信号,则select返回-1且同时设置errno为EINTR。
struct timeval {
long tv_sec; //seconds
long tv_usec; //microseconds
};
select函数的作用是告诉内核那些文件描述(读、写、异常条