IO发生时经历的过程
对于一个network IO (以read读取为例) ,它涉及到两个对象,一个是系统调用这个IO操作的process(or therad) ,另一个是系统内核(kennel,当一个read)操作发生时,它会经历的两个阶段:
等待数据准备(waiting for the data to be ready)
将数据从内核拷贝到进程中(copying the data from the kernel to the process)

同步 sysnchronous
同步IO,又称阻塞,出现阻塞就被称为同步
同步需要主动读写数据,在读写数据的过程中还是会阻塞

IO 异步asynchronous

全程无阻塞
告知内核启动某个操作,并让内核在整个操作完成后(包括将数据从内核空间拷贝到自己的缓冲区)通知。异步IO的主要特点是完成操作后主动通知。
如图:

阻塞
进程直到执行操作完成
阻塞是最常用的IO模型,默认情况下所有的文件操作都是阻塞的。以套接字编程为例。在进程空间中调用recvfrom,其系统调用直到数据报文到达且被拷贝到应用程序进程的缓存区(或者发生错误)后才返回,期间一直在等待。进程在从调用recvfrom开始到它返回的整段时间内是被阻塞的。
– 如图:

非阻塞IO non-blocking

调用recvfrom从应用层到内核的过程中,如果该缓冲区没有数据的话,则直接返回一个EWOULDBLOCK的错误,一般会轮询的进行检查状态,看内核空间有没有数据来。直到有数据,最后完成拷贝。
非阻塞优点及缺点:
发生多次系统调用时:
优点: wait for data 时无阻塞
缺点:1、系统调用太多 2、数据不是实时接收的

IO多路复用

Linux系统提供的select/poll/epoll,进程将一个或者多个FD(文件描述符)传递给一个或者多个poll/select系统调用,阻塞在select。select和poll可以帮助侦听很多的FD是否准备就绪。但是,select和poll是顺序扫描去检查FD的就绪状态,效率比较低,而且支持的FD数量有限(没记错的话,默认好像是1024)。而epoll是通过事件驱动的方式,当有FD准备就绪的时候,立即回调函数rollback。
如图:

五种模型总结:

打赏作者

Leave a Reply

Your email address will not be published.