IO的学习笔记 - 同步,异步,阻塞,非阻塞
这几天花了些时间研究IO的相关概念,记录下自己的一些学习思考。
网上太多的文章都是你抄我,我抄你,真正是害人不浅。在这里特别介绍一篇好文:《IO - 同步,异步,阻塞,非阻塞(亡羊补牢篇)》
总结下自己的学习心得:
一. 网络IO都必须经历的两个阶段:
对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。当一个read操作发生时,它会经历两个阶段:
1 等待数据准备 (Waiting for the data to be ready)
2 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)
这两个阶段是所有IO模型都会经历的,他们的区别也体现在这两个阶段的不同。
二. 阻塞IO和非阻塞IO的区别
阻塞IO在操作全部进行完之前会一直block进程。
非阻塞IO在内核准备数据时,会马上返回,不会block住进程
三. 同步与异步的区别
英文介绍:
A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes;(同步)
An asynchronous I/O operation does not cause the requesting process to be blocked; (异步)
阻塞IO,非阻塞IO都是属于同步,这里是玩了一个“文字游戏”:
“有人可能会说,non-blocking IO并没有被block啊。这里有个非常“狡猾”的地方,定义中所指的”IO operation”是指真实的IO操作,就是例子中的recvfrom这个system call。non-blocking IO在执行recvfrom这个system call的时候,如果kernel的数据没有准备好,这时候不会block进程。但是,当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存中,这个时候进程是被block了,在这段时间内,进程是被block的。而asynchronous IO则不一样,当进程发起IO 操作之后,就直接返回再也不理睬了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被block”
四. 举例
最后,再举几个不是很恰当的例子来说明这四个IO Model:
有A,B,C,D四个人在钓鱼:
A用的是最老式的鱼竿,所以呢,得一直守着,等到鱼上钩了再拉杆;(阻塞IO)
B的鱼竿有个功能,能够显示是否有鱼上钩,所以呢,B就和旁边的MM聊天,隔会再看看有没有鱼上钩,有的话就迅速拉杆;(非阻塞IO)
C用的鱼竿和B差不多,但他想了一个好办法,就是同时放好几根鱼竿,然后守在旁边,一旦有显示说鱼上钩了,它就将对应的鱼竿拉起来;(IO多路复用(I/O multiplexing))
D是个有钱人,干脆雇了一个人帮他钓鱼,一旦那个人把鱼钓上来了,就给D发个短信。 (异步IO)