Linux网络编程的5中I/O模型(简单明了)
目录
5.异步I/O(重点)POSIX的aio_系列函数) Future-Listener机制;
一 简单例子了解同步/异步 阻塞/非阻塞
人相当于线程/进程
先洗后晒 先请求再处理
数据-->晒干(同步|异步)
请求-->洗衣机洗衣服(阻塞|非阻塞)线程/进程
1.同步阻塞:
放到洗衣机洗衣服等着洗完,在晒衣服等着晒完(你就干等,啥都不做,阻塞在那边)
2.同步非阻塞:
放到洗衣机里洗衣服,之后到客厅去干其他事,时不时的到阳台看一下衣服是否洗完,再去晒衣服
(等待期间你可以做其他事情)
3.异步阻塞:
你把衣服丢到洗衣机洗,然后看着洗衣机洗完,洗好后再去晾衣服(几乎没这个情况,几乎没这个说法,可以忽略)
4.异步非阻塞:
你把衣服丢到洗衣机洗,然后会客厅做其他事情,洗衣机洗好后会自动去晾衣服,晾完成后放个音乐告诉你洗好衣服并晾好了
同步和异步看的是数据的真正的IO处理 阻塞和非阻塞看数据的请求处理
一个IO操作可以分为两个步骤:发起IO请求和实际的IO操作
例如:
1、操作系统的一次写操作分为两步:将数据从用户空间拷贝到系统空间;从系统空间往网卡写。
2、一次读操作分为两步:将数据从网卡拷贝到系统空间;将数据从系统空间拷贝到用户空间。
阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。
同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非阻塞IO、IO复用、信号驱动IO都是同步IO,如果不阻塞,而是操作系统做完IO两个阶段的操作再将结果返回,那么就是异步IO。
阻塞非阻塞:线程是否等在这等待
同步:主动的读写数据(自己完成)
异步:os帮我们完成了(别人完成)
二 Linux网络编程中的五种I/O模型分析
网络IO,用户程序和内核的交互为基础进行讲解
IO操作分两步:发起IO请求等待数据准备,实际IO操作(洗衣服,晾衣服)
同步须要主动读写数据,在读写数据的过程中还是会阻塞(好比晾衣服阻塞了你)
异步仅仅须要I/O操作完毕的通知。并不主动读写数据,由操作系统内核完毕数据的读写(机器人帮你自动晾衣服)
五种IO的模型:阻塞IO、非阻塞IO、多路复用IO、信号驱动IO和异步IO
前四种都是同步IO,在内核数据copy到用户空间时都是阻塞的
1.阻塞IO
线程阻塞于recvform的调用
2.非阻塞IO
3.多路复用IO
I/O多路复用是阻塞在select,epoll这样的系统调用,没有阻塞在真正的I/O系统调用如recvfrom
进程受阻于select,等待可能多个套接口中的任一个变为可读
IO多路复用使用两个系统调用(select和recvfrom)
blocking IO只调用了一个系统调用(recvfrom)
select/epoll 核心是可以同时处理多个connection,而不是更快,所以连接数不高的话,性能不一定比多线程+阻塞IO好
多路复用模型中,每一个socket,设置为non-blocking,
阻塞是被select这个函数block,而不是被socket阻塞的
4.信号驱动式I/O(SIGIO)(用的很少)
同步模型recvfrom函数在copy的时候都会等待(自己总结可能不是很准确)
5.异步I/O(重点)POSIX的aio_系列函数) Future-Listener机制;
Future-Listener机制使os帮我们做好了io操作(机器人帮我们洗衣服晒衣服晒好了给通知的信号)不需线程主动进行copy内核都帮我们做好了
回调机制
6.总结
IO操作分为两步
1)发起IO请求,等待数据准备(Waiting for the data to be ready)
2)实际的IO操作,将数据从内核拷贝到进程中(Copying the data from the kernel to the process)
前四种IO模型都是同步IO操作,区别在于第一阶段,而他们的第二阶段是一样的:在数据从内核复制到应用缓冲区期间(用户空间),进程阻塞于recvfrom调用或者select()函数。 相反,异步I/O模型在这两个阶段都要处理。
阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。
同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO,因此阻塞IO、非阻塞IO、IO复用、信号驱动IO都是同步IO,如果不阻塞,而是操作系统帮你做完IO操作再将结果返回给你,那么就是异步IO。
几个核心点:
阻塞非阻塞说的是线程的状态(重要)
线程是否可以继续向下走做别的事情
同步和异步说的是消息的通知机制(重要)
别人告诉 (异步)
自己去找(同步)
同步需要主动读写数据,异步是不需要主动读写数据
同步IO和异步IO是针对用户应用程序和内核的交互