文章目录
五种IO模型
同步阻塞IO
同步模型也是比较简单的模型,指的是当我们去调用相应的系统调用时,会导致在用户态的进程处于阻塞状态,等待在内核态处理任务完成后拿到想要的数据才会继续往下执行的模型。所以在从用户态到内核态,在回到用户态的时间段内。进程是需要阻塞等待的。就像去楼下拿外卖,外卖小哥在下楼这段时间是不能去送其他东西,处于一个等待阻塞的状态。
非阻塞IO
非阻塞也就顾名思义,他不会有阻塞IO中一直等待的那个状态,进程在执行系统调用,进程不会处于阻塞状态,进程会不断的询问缓存区中需要的数据是否准备好了。如果没有则会返回EWOULDBLOCK状态,这时进程知道了自己想要的东西还没有准备好,会继续对需求的数据进行询问。
异步IO(asynchronous IO)
异步的特性是相对于同步的,进程执行系统调用后会立即返回,进程不会阻塞,会继续执行接下来的逻辑。当进程需要的数据准备好后,内核态会将数据放入用户缓冲区后给进程通知,然后进程可以直接去做拿到相应数据的那些逻辑。
信号驱动式IO(signal-driven IO)
信号驱动IO和异步IO很像。当进程执行相应的系统调用开始后,进程依然可以正常执行,不会被阻塞。当数据被准备好后,会通过信号通知给相应的进程,进程在收到通知后,在从内核态拿数据到用户缓冲区的这个过程中,进程会处于阻塞状态。这也是信号驱动和异步IO的一个区别。
多路复用IO(multiplexing IO)
在这种模型下,进程会受阻于select,poll或epoll函数。这两个函数能够阻塞多个I/O操做,能够同时对多个读操做和多个写操做进行检测,直到数据变成可读或可写时,即数据已经加载到buffer中。才真正调用I/O操做函数,而后再将buffer中的数据复制到用户进程缓存区中,而后进程读取其数据,最后返回给客户端。
SElECT
select函数主要使用了轮询的方式来取监听多个事件是否发生的。select采用了位图这样的数据结构,来反映哪些事件需要被监听,哪些事件已经就绪。
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
// 第一个参数nfds是监视的文件描述符中最大值加一,