码迷,mamicode.com
首页 > 系统相关 > 详细

linux网络IO模型——阻塞、非阻塞和同步、异步

时间:2016-06-05 12:23:16      阅读:322      评论:0      收藏:0      [点我收藏+]

标签:

最近几天在学习nginx的时候了解了一下linux网络IO模型,在此谈谈我自己的理解,如有错误请多多指教。本文参考书籍Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking ”,6.2节“I/O Models ”。

Linux网络IO请求数据分为两段:

  1.数据准备

  2.将数据从内核拷贝到进程空间

其实,阻塞、非阻塞和同步、异步的不同就在于这两个阶段的不同。

同步和异步关注的是消息通信机制

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态

阻塞(blocking IO)

  linux中,默认情况下socket都是阻塞的,大致过程如下:

  技术分享

如图,进程发起recvform后,内核进行第一阶段准备数据,但是很多时候数据开始时不会全部到达,对于进程来说就处于blocking状态,数据准备好后,内核将数据拷贝到进程空间,拷贝完毕后kernel返回结果,进程结束阻塞状态。即blocking IO两个阶段全部处于blocking状态。

 

非阻塞(non-blocking IO)

  linux中我们可以设置socket为non-blocking,当发出的IO请求没有完成时,不是把进程转为睡眠态,而是返回一个error。

  技术分享

如图所示,当用户发起read时,数据若没有准备好,kernel会立即返回一个error,不需要等待。当进程收到error(EWOULDBLOCK)后,知道数据还没有准备好,之后继续发送read请求。kernel会继续收到进程的system call请求,直到数据准备好,内核会将数据拷贝到用户进程空间。这种模型需要进程不间断的发起system call请求,这会造成cpu时间的浪费。

 

IO复用(IO Multiplexing)

  IO复用多数人所知的是select,poll。select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select/poll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。大致过程如下:

  技术分享

当用户进程调用了select,整个进程就会被阻塞。同时内核会轮询查看所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候用户进程再调用system call,将数据从kernel拷贝到用户进程空间。

这个模型和blocking IO相比,并没有多大的优势,甚至有时候还不如blocking IO。select/poll的优势是可以同时处理多个connection,并不是单个connection处理得更快。

 

异步IO(Asynchronous I/O Model)

  技术分享

用户进程发起system call调用之后,就可以去做其他事了。从kernel的角度,当它收到一个aio_read之后,它会立刻返回,所以不会对用户进程产生blocking。kernel会等待数据准备完成,然后将数据拷贝到用户内存,拷贝完成后,kernel会给用户进程发送一个signal,告诉它read操作完成了。

 

blocking和non-blocking的区别:

  blocking会一直阻塞进程直到操作完成,non-blocking在内核准备数据的时候会立即返回。

 

同步synchronous I/O 和异步asynchronous I/O的区别

  synchronous io在请求数据的过程中存在阻塞,asynchronous io在请求数据的过程中不存在阻塞。

各种IO模型比较:

  技术分享

如图,blocking,non-blocking,I/O multiplexing均属于synchronous IO。

linux网络IO模型——阻塞、非阻塞和同步、异步

标签:

原文地址:http://www.cnblogs.com/jdxupt/p/5560384.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!