很多人对阻塞,非阻塞,同步,异步,并发,竞态的概念不是很清晰,今天我把我理解的用一个模型来说明一下这些概念。
首先建立一个模型:
我们去银行办理业务,屌丝的做法是:
1、银行未准备好,则一直排队,直到前面的人告诉你可以办理了,则你去处理业务
2、一到银行,看银行未准备好,要么转身就走;要么在大厅里面坐着,一直看着银行有没有准备好。
3、先看看银行有没有准备好。如果有,则自己办理业务,如果没有,则出去晃一圈,再回来,看有没有,依次循环。
高富帅的做法是:
1、先和银行打一个招呼,过一段时间,银行看自己准备好了,通知你过去办理业务。
2、你要把你需要办理的业务和银行先说一下,然后回家等待,银行业务办好了的通知你,告诉你办好了。 (说明一下银行未准备好指:客户要取的,
没有;要存时,满了;有其他客户在办理业务。从内核的观点讲就是阻塞的情况)
那么从上面的例子可以看出,屌丝的共同点是什么呢?就是去银行办业务,都是亲力亲为,即先看银行条件允许没,再自己去办理业务。而高富帅只
要先和银行打下招呼,当银行准备好时,
它会通知你,甚至,他可以把你交予的任务完成直接告诉你结果。
上图部分把我们的模型和内核的一些概念联系了起来,下面我把一些概念再解释一下:
同步的定义:由处理消息者自己去等待消息是否被触发(屌丝都要自己去看看银行有么有人正在办理业务)
异步的定义:由触发机制来通知处理消息者(高富帅是银行通知你已经办好业务了)
阻塞:当你读取文件。若为空,你不能读取文件,这是就要阻塞;若文件满时,你不能写文件,这要阻塞。(当客户要取自己存在银行里面的保险
柜东西,若里面没有东西,自然不行,直到有人往里面存东西)当两个进程同时操作一个设备文件,就会发生竞态,这时也会发生阻塞。总而言之:
当文件没有准备好时,睡眠,你就要一直等它就绪,才能对其操作。
非阻塞:当你读取文件时,文件没有准备好,或者'你'可以转身作别的事情,或者一直询问他有没有准备好。
讲完上面几个概念,下面可以理解下屌丝高富帅的几个行为了: 屌丝(同步)的做法:
1、银行未准备好,则一直排队,直到前面的人告诉你可以办理了,则你去处理业务。 这是阻塞型读写。当以阻塞方式read(),write()时,要取的,
没有;要存时,满了;有其他进程在存取。进程睡眠。其他进程唤醒你,或者其他进程释放信号量。此时可以读写。
2、一到银行,看银行未准备好,要么转身就走;要么在大厅里面坐着,一直看着银行有没有准备好。 这是非阻塞型读写。 当以非阻塞方式read(),
write()时,要取的,没有;要存时,满了;有其他进程在存取。此时要么返回,进行其他操作;要么继续查询银行有没有准备好。
3、先看看银行有没有准备好。如果有,则自己办理业务,如果没有,则出去晃一圈,再回来,看有没有,依次循环。若准备好了,再进行读写。
这里把读取过程分为两步:先询问银行准备好没;读取数据。而上面屌丝做法1、2把这两步并成了一步。这种我们把它称为select(),poll()的方法。
调用select()时,它先会把可读\可写的状态放在fd中,若是可读\可写,则在调用read(),write()。
高富帅的做法:
1、先和银行打一个招呼,过一段时间,银行看自己准备好了,通知你过去办理业务。 这是异步通知的机制。这里打一个招呼指,启动FASYNC机制
。进程是通过函数singal(SIGIO,handle)来通知你去办理业务的。
2、你要把你需要办理的业务和银行先说一下,然后回家等待,银行业务办好了的通知你,告诉你办好了。 这是AIO机制。 这里通过aio_read()\aio_write()
来通知发送,接受一个数据,通过aio_error()、 aio_return()来通知你是否完成数据的处理。
有几篇博文讲的不错,但是有的还是有点问题:
http://www.cppblog.com/converse/archive/2009/05/13/82879.html 这篇博文博主讲的不是很正确,但是| 啸天猪这个同学的观点我很认同。。。。。。。。。。。
同步: '你'亲自办这件事
异步: 交代要做的事情,然后忙其他的事情;'别人'(内核)会充当你的跑腿,在条件就绪后将这事办成,然后通知你(callback);
阻塞: 如果条件未就绪,'你'必须死等它就绪;进程睡眠
非阻塞:如果条件未就绪,'你'可以转身作别的事情;进程可以作任何想做的事情,不过通常是低效的轮询。
以这种理解方式,阻塞/非阻塞只对同步操作有意义;异步I/O总是意味着进程不会因为I/O陷入睡眠。
将" select"归类为异步+blocking不妥,select实际上完成的只是read/write的第一部分:等待条件就绪;唯一的改进是可以等待多个条件。"select + read/write"的调用形式容易产生"系统通知我条件就绪"的假象,可实际上你不过是在条件就绪的时候醒来,然后仍然亲自动手完成了数据复制的操作。
依然使用银行的隐喻:
柜台R:只能取款
柜台W:只能存款
read: 亲自在柜台R排队(进程睡眠) + 取款
write: 亲自在柜台W排队(进程睡眠) + 存款
select + read/write : 亲自同时在R、W两个柜台排队(进程睡眠) + (存款|取款|存款+取款)
AIO : 告诉心腹小弟要取款若干,然后忙别的事情;小弟取款完毕将其如数奉上。
UNP一书中6.2节对I/O模型的分类我觉得很合理:
1).read/write、read + NON_BLOCK、select、signal driven I/O 都属于同步I/O; 它们的共同特点是:将数据从内核空间复制到到用户空间的这个操作,是由用户空间的代码显式发起的。
2).只有AIO 属于 异步I/O;内核不露声色的将数据从内核空间复制到用户空间,然后通知进程。
分享到:
相关推荐
第二篇 勿于浮砂筑高台——Linux驱动基础篇 第3章Linux内核综述 3.1 OS基本概念 3.1.1多用户系统 3.1.2用户和组 3.1.3进程 3.1.4 Linux单核架构 3.2 Linux内核综述 3.2.1进程/内核模型综述 3.2.2内存管理综述 3.2.3...
9.1 阻塞和非阻塞、同步和异步与 IO 操作 9.2 阻塞 IO 9.2.1 等待队列 9.3 实验 9.3.1 原理图 9.3.2 设备树 9.3.3 驱动
在类unix系统中有五大I/O模型,依次为阻塞IO(BIO)、非阻塞IO(NIO)、IO多路复用(linux下有select、poll、epoll三种方案)、信号驱动IO、异步IO(前面四种都是同步IO),本文主要介绍常用的C的IO库,几乎都是...
第十一章 异步 IO这里要说的异步 IO 准确的说应该叫“信号驱动的异步 I/O”,也可以成为异步通知。前面两章说的阻塞和非阻塞 IO,他们都是同步 IO,需要
目 录 第1篇 Linux网络开发基础 ...9.6.1 非阻塞方式程序设计介绍 264 9.6.2 非阻塞程序设计的例子 264 9.7 小结 266 第10章 基于UDP协议的接收和发送 267 10.1 UDP编程框架 267 10.1.1 UDP编程框图 267
Tencent Server Framework 是快速服务器部署框架,PHP 现在可以像 Golang 一样用协程实现高并发服务器,同时支持同步阻塞,异步非阻塞回调,协程这 3 种 IO 模型。 主要特性: 基于 PHP,相比 C 开发更高效 ...
6.10.2 非阻塞模式I/O.... 180 6.10.3 I/O 多路复用.... 181 6.10.4 信号驱动I/O 模式........... 182 6.10.5 异步I/O 模式... 185 6.10.6 几种I/O 模式的比较........ 186 6.10.7 fcntl()函数........ 186 6.10.8 ...
3.1 进程的建立与运行 ...........................................................................................22 3.1.1 进程的概念 .......................................................................
02 并发并行与同步异步的概念 03 GIL的概念 04 同步锁 05 递归锁 06 同步对象event 07 信号量 08 线程队列 09 生产者消费者模型 10 多进程的调用 第35章 01 进程通信 02 进程池 03 协程 04 事件驱动模型 05 IO模型...
1.3 Linux 与 U N I X 的异同.................................................. 5 1 . 4 操作系统类型选择和内核版本的选择..................................... 5 1.4.1常见的不同公司发行的Linux异同...........
它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JS...
Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...
3.1 进程的建立与运行 ...........................................................................................22 3.1.1 进程的概念 .....................................................................
Java数据压缩与传输实例,可以学习一下实例化套按字、得到文件输入流、压缩输入流、文件输出流、实例化缓冲区、写入数据到文件、关闭输入流、关闭套接字关闭输出流、输出错误信息等Java编程小技巧。 Java数组倒置...
它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JS...
它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JS...
它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JS...
它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JS...