5种网络IO模型(有图,很清楚)( 五 )


还有一种不常用的signal driven IO , 即信号驱动IO 。 总的来说 , UNP中总结的IO模型有5种之多:阻塞IO , 非阻塞IO , IO复用 , 信号驱动IO , 异步IO 。 前四种都属于同步IO 。 阻塞IO不必说了 。 非阻塞IO, IO请求时加上O_NONBLOCK一类的标志位 , 立刻返回 , IO没有就绪会返回错误 , 需要请求进程主动轮询不断发IO请求直到返回正确 。 IO复用同非阻塞IO本质一样 , 不过利用了新的select系统调用 , 由内核来负责本来是请求进程该做的轮询操作 。 看似比非阻塞IO还多了一个系统调用开销 , 不过因为可以支持多路IO , 才算提高了效率 。 信号驱动IO , 调用sigaltion系统调用 , 当内核中IO数据就绪时以SIGIO信号通知请求进程 , 请求进程再把数据从内核读入到用户空间 , 这一步是阻塞的 。 异步IO , 如定义所说 , 不会因为IO操作阻塞 , IO操作全部完成才通知请求进程 。各个IO Model的比较如图所示:
5种网络IO模型(有图,很清楚)文章插图
图12 各种IO模型的比较
经过上面的介绍 , 会发现non-blocking IO和asynchronous IO的区别还是很明显的 。 在non-blocking IO中 , 虽然进程大部分时间都不会被block , 但是它仍然要求进程去主动的check , 并且当数据准备完成以后 , 也需要进程主动的再次调用recvfrom来将数据拷贝到用户内存 。 而asynchronous IO则完全不同 。 它就像是用户进程将整个IO操作交给了他人(kernel)完成 , 然后他人做完后发信号通知 。 在此期间 , 用户进程不需要去检查IO操作的状态 , 也不需要主动的去拷贝数据 。