5种io模型摘要
https://www.jianshu.com/p/db5da880154a
I/O多路复用,I/O就是指的我们网络I/O,多路指多个TCP连接(或多个Channel),复用指复用一个或少量线程。串起来理解就是很多个网络I/O复用一个或少量的线程来处理这些连接。
理解了select就抓住了I/O多路复用的精髓,对应的操作系统中调用的则是系统的select函数,该函数会等待多个I/O事件(比如读就绪,写)的任何一个发生,并且只要有一个网络事件发生,select线程就会执行。
IO多路复用模型使用了Reactor设计模式实现了这一机制。
异步IO模型使用了Proactor设计模式实现了这一机制。
https://segmentfault.com/a/1190000007355931
根据 POSIX 定义:
-
A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes(导致请求进程阻塞, 直到 IO 操作完成).
-
An asynchronous I/O operation does not cause the requesting process to be blocked(不导致请求进程阻塞).
根据上述定义, 我们的前四种模型: 阻塞 IO 模型, 非阻塞 IO 模型, IO 复用模型和信号驱动 IO 模型都是同步 IO 模型, 因为其中真正的 IO 操作(recvfrom 调用) 会阻塞进程(因为当有数据时, recvfrom 会阻塞等待内核将数据从内核空间复制到应用进程空间, 当赋值完成后, recvfrom 才返回.
) 只有异步 IO 模型与 POSIX 定义的异步 IO 相匹配.
||
||
||
小结:
1 传统的多线程bio模型从内核io的角度是同步阻塞的,致命弱点是
1.1 连接多了,线程切换对CPU的压力
1.2 僵尸连接占用线程
2 io多路复用的非阻塞体现在哪里
2.1 有人称多路复用为同步非阻塞,其非阻塞针对用户线程在第一阶段轮询众多连接同步的io请求是否有返回上,(select请求内核仍然是同步阻塞请求,但其非阻塞体现在select在内核中干的事情-不断非阻塞轮训各连接是否有io读写,是非阻塞的),至于第二阶段,多路复用既是同步又是阻塞的,线程需要顺序阻塞线程地的一个一个连接排队把内核数据复制到用户空间,当赋值完成后, recvfrom 才返回
同步非阻塞,同步体现在 selector 轮循判断 channel 是否准备好这个请求是同步请求,系统没结果不会返回,非阻塞体现在轮询这个过程中处理线程不会一直在吊死在一棵树上(一个channel),可以去做其他的事情(其它channel)。
其实通知你是告诉你内核准备好了,你取数据的时候还是需要将内核中的数据拷贝到用户空间中(即io第二阶段)。这段时间进程是会阻塞的
2.3 https://blog.csdn.net/historyasamirror/article/details/5778378
整个用户的process其实是一直被block的。只不过process是被select这个函数block,而不是被socket IO给block。
用户态同步阻塞,内核态同步非阻塞-轮训
3 多路复用比非阻塞模型强在哪里
https://blog.csdn.net/ocean_fan/article/details/79622956
从实践模拟角度再议bio nio【yetdone】 给出了一个由非阻塞模型-io复用模型的演变过程
4 目前以多路复用为主,全异步io模型需要操作系统更多更个性化的支持