网络编程释疑之:同步,异步,阻塞,非阻塞

一讲到网络编程的I/O模型,总会涉及到这几个概念。问了不少人,没几个能清晰地讲出他们之间的区别联系,甚至在网络上也有不少不一样的观点,也不知是中国文字释义的博大精深,仍是原本这几个概念就是绕人不倦。今天我也来给你们讲解一下我对这几个概念的理解。编程


既然网络上众说纷纭,不如找个权威参考一下,这个权威就是《UNIX网络编程:卷一》第六章——I/O复用。书中向咱们说起了5种类UNIX下可用的I/O模型:网络

  • 阻塞式I/O;异步

  • 非阻塞式I/O;ide

  • I/O复用(select,poll,epoll...);函数

  • 信号驱动式I/O(SIGIO);spa

  • 异步I/O(POSIX的aio_系列函数);操作系统

阻塞式I/O模型:默认状况下,全部套接字都是阻塞的。怎么理解?先理解这么个流程,一个输入操做一般包括两个不一样阶段:线程

(1)等待数据准备好;
(2)从内核向进程复制数据。blog


对于一个套接字上的输入操做,第一步一般涉及等待数据从网络中到达。当全部等待分组到达时,它被复制到内核中的某个缓冲区。第二步就是把数据从内核缓冲区复制到应用程序缓冲区。 好,下面咱们以阻塞套接字的recvfrom的的调用图来讲明阻塞进程

202707564.jpg

标红的这部分过程就是阻塞,直到阻塞结束recvfrom才能返回。

非阻塞式I/O: 如下这句话很重要:进程把一个套接字设置成非阻塞是在通知内核,当所请求的I/O操做非得把本进程投入睡眠才能完成时,不要把进程投入睡眠,而是返回一个错误。看看非阻塞的套接字的recvfrom操做如何进行

202858660.jpg

能够看出recvfrom老是当即返回。

I/O多路复用:虽然I/O多路复用的函数也是阻塞的,可是其与以上两种仍是有不一样的,I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上。如图

202009980.jpg

信号驱动式I/O:用的不多,就不作讲解了。直接上图

202028686.jpg

异步I/O:这类函数的工做机制是告知内核启动某个操做,并让内核在整个操做(包括将数据从内核拷贝到用户空间)完成后通知咱们。如图:

202055894.jpg

注意红线标记处说明在调用时就能够立马返回,等函数操做完成会通知咱们。

等等,你们必定要问了,同步这个概念你怎么没涉及啊?别急,您先看总结。 其实前四种I/O模型都是同步I/O操做,他们的区别在于第一阶段,而他们的第二阶段是同样的:在数据从内核复制到应用缓冲区期间(用户空间),进程阻塞于recvfrom调用。相反,异步I/O模型在这两个阶段都要处理。

wKiom1LLqEPC2DSMAAUHeILYGZ4097.jpg

再看POSIX对这两个术语的定义:

  • 同步I/O操做:致使请求进程阻塞,直到I/O操做完成;

  • 异步I/O操做:不致使请求进程阻塞。

好,下面我用个人语言来总结一下阻塞,非阻塞,同步,异步

  • 阻塞,非阻塞:进程/线程要访问的数据是否就绪,进程/线程是否须要等待;

  • 同步,异步:访问数据的方式,同步须要主动读写数据,在读写数据的过程当中仍是会阻塞;异步只须要I/O操做完成的通知,并不主动读写数据,由操做系统内核完成数据的读写。

相关文章
相关标签/搜索