前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >也谈应用程序级的同步、异步、阻塞、非阻塞

也谈应用程序级的同步、异步、阻塞、非阻塞

作者头像
chain
发布2018-08-02 15:13:07
9800
发布2018-08-02 15:13:07
举报

同步IO(synchronous)

异步IO(asynchronous)

阻塞IO(blocking)

非阻塞IO(non-blocking)

这几个经常出现的词汇很容易会引起大家的误解,第一次接触相关词汇是在课上,当时上操作系统的老师说得比较模糊(阻塞==同步,非阻塞==异步),当时觉得挺对 的,

初学者一般来说很会这么认为。但是后来随着对操作系统的进一步认识和学习,以及参考其他的一些资料,今天就在这帮大家理一理这四个概念以及相关的联系。

阻塞,在操作系统的书中都有相关的概念,简单的说 就是线程或是进程在执行过程中暂停,以等待某个条件的触发。

同步,指的就是两个或多个以上的进程保持相互的制约,一般多用在 通信当面的词。

接下来就说一上述困扰大家的四个词之间的相互关系:

同步阻塞IO:

应用场景:

应用程序A执行了一个read操作,然后这个read操作会去进行一个系统调用(system call),转交给内核,应用程序便会等待(阻塞),kernel便会开始执行系统调用,执行

完成之后将结果返回给应用程序,应用程序得到结果后就不在阻塞,继续后续的过程。

打个比方就是,你去医药窗口花钱买药 ,告诉药剂师要买一盒感冒药,药剂师就去帮你去里面的药架上找感冒药,你就站在窗口等,他找到后拿到窗口给你,其实就是一

个同步阻塞的过程。

同步非阻塞IO:

应用场景:

在linux下,应用程序可以通过设置文件描述符的属性O_NONBLOCK,I/O操作可以立即返回,但是并不保证I/O操作成功。也就是说,当应用程序设置了O_NONBLOCK之

后,执行write操作,调用相应的system call,这个system call会从内核中立即返回。但是在这个返回的时间点,数据可能还没有被真正的写入到指定的地方。也就是说,kern

el只是很快的返回了这个 system call(这样,应用程序不会被这个IO操作blocking),但是这个system call具体要执行的事情(写数据)可能并没有完成。而对于应用程序,

虽然这个IO操作很快就返回了,但是它并不知道这个IO操作是否真的成功了,如果想知道,需要应用程序主动地去问kernel。

打个比方就是,你去邮局寄东西(东西很重要,对方拿到后你才能够继续进行工作),填好 单子付完款后,邮局工作人员会告诉你,大概要三天到(邮局今天的囤货太多

了,改到明天发),然后你本人肯定就回去了,在家里等啊等,并且时不时的查查到哪了(不能继续进行下面的工作啊,诶 :( )。终于三天后收件人发信息说已经收到,你终

于可以开展你的下一步工作了 :)

异步阻塞IO:

应用场景:

在linux下,通常用select/poll来实现这种机制。应用程序要执行read操作,因此调用一个system call,这个system call被传递给了kernel。但在应用程序这边,它调用syst

em call之后,并不等待kernel返回响应,这一点是和前面两种机制不一样的地方。这也是为什么它被称为异步的原因。但是为什么称其为阻塞呢?这是因为虽然应用程序是一

个异步的方式,但是select()函数会将应用程序阻塞住,一直等到这个system call有结果返回了,再通知应用程序。也就是说,“在这种模型中,配置的是非阻塞 I/O,然后使用

阻塞 select 系统调用来确定一个 I/O 描述符何时有操作。”所以,从IO操作的实际效果来看,异步阻塞IO和第一种同步阻塞IO是一样的,应用程序都是一直等到IO操作成功之后

(数据已经被写入或者读取),才开始进行下面的工作。异步阻塞IO的好处在于一个select函数可以为多个描述符提供通知,提高了并发性。

打个比方就是,一个银行柜台,现在有10个人想存钱。按照现在银行的做法,一个个排队。第一个人先填存款单,然后提交,然后柜员处理,然后给回执,成功后再轮到

下一个人。大家应该都在银行排过对,这样的流程是很痛苦的。如果按照异步阻塞的机制,10个人都填好存款单,然后都提交给柜台,提交完之后所有的10个人就在银行大厅

等待。这时候会专门有个人,他会了解存款单处理的情况,一旦有存款单处理完毕,他会将回执交给相应的正在大厅等待的人,这个拿到回执的人就可以去干其他的事情了。

而前面提到的这个专人,就对应于select函数。

异步非阻塞IO:

应用场景:

应用程序提交read请求的system call,然后,kernel开始处理相应的IO操作,而同时,应用程序并不等kernel返回响应,就会开始执行其他的处理操作(应用程序没有被I

O操作所阻塞)。当kernel执行完毕,返回read的响应,就会产生一个信号或执行一个基于线程的回调函数来完成这次 I/O 处理过程。

打个比方就是,上述邮局寄东西,你寄完东西后不需要干等着,而可以干别的事情,等到收件人给你发收件信息后,你在回过头干之前没干完的工作。

总的来看的话,对于同步和异步,指的都是应用程序级的,而所谓的阻塞和非阻塞的话,指的是在内核调度进程或线程方面的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013年10月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档