举例说明 同步 异步 阻塞 非阻塞

有趣的小栗子?

一个小故事

故事:小A烧开水。

出场人物:小A出场道具:普通水壶(放在煤气灶上的那种,为了方便简称:水壶);会响的水壶(水烧开了会响的那种,简称:响壶)。故事目的:小A要拿开水泡咖啡

小A为了实现目的,指定了4个计划:

1、用水壶烧水,并且站在煤气灶旁边,啥事不干,两眼直勾勾的盯着水壶,等水烧开。烧开后就去泡咖啡。同步阻塞

假设烧水和泡咖啡是在同一个线程中执行。

2、仍然用水壶煮水,不过此时不再傻傻得站在那里看水开没开,而是去玩局LOL,每当自己死了,就过来看看水开了没有。如果水开了就去泡咖啡。同步非阻塞

假设这里玩LOL,是另一个线程运行的。

3、动用响壶烧水,仍然站在煤气灶旁边,不过此时不两眼直勾勾的盯着壶了,而是听响,因为响壶水开时会用响声通知小A。异步阻塞

4、在计划3的基础上,小A不站在煤气灶旁边了,而是去玩局LOL,等听到响壶的声音提醒后,再去跑咖啡。异步非阻塞

有了上边的故事铺垫,我们再来看一看概念

同步:

同步这个词在很多场合下都会被使用,如果单从字面意思来看:相同的步骤。但是在编程的领域里讲,字面意思就不那么准确了。

对于编程领域来说,同步就是发起一个请求,直到请求返回结果之后,才进行下一步操作。简单来说,同步就是必须一件事一件事的做,等前一件做完了,才能做下一件事。

例子:此种模式很常见,比如我发起一个网络请求查询一个人的身份证,然后根据身份证查看这个人的详细信息。那么我查询详细信息的操作需要等待查询身份证的操作,那么此时查询身份证的操作就是一个同步操作。

异步:

异步很明显是与同步相对,二者的区别在于是否需要等待某操作的返回结果。简单来说,我们还是一个网络请求,如果我们此时不需要依赖这个请求的结果就能进行后续操作,那么此时这个网络请求就是一个异步操作。

当一个异步操作发出后,调用者在没有得到结果之前,可以继续执行后续操作。这就是异步。

同步和异步的区别:

二者的区别还是很明显的:请求发出后,是否需要等待请求结果,才能继续执行其他操作。

阻塞

阻塞的概念往往伴随着线程。阻塞一般是指:在调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会被唤醒执行后续的操作。

非阻塞

那么非阻塞,毫无疑问是阻塞的反向操作。非阻塞式的调用指:在结果没有返回之前,该调用不会阻塞住当前线程。

是不是感觉阻塞/非阻塞和同步/异步有异曲同工的地方?

其实,这两者存在本质的区别,面向的对象是不同的。

阻塞/非阻塞:进程/线程需要操作的数据如果尚未就绪,是否妨碍了当前进程/线程的后续操作。同步/异步:数据如果尚未就绪,是否需要等待数据结果。

并发和并行

二者的区分度非常的高,就在于四个字:是否同时

并发:当有多个线程在操作时,如果系统只有一个CPU,操作系统只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的快速的切换不同的线程代码运行。

并行:当系统有多个CPU时,可以存在当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行。

举个小例子

小A吃饭吃到一半,电话来了,小A一直到吃完了以后才去接。既不支持并发也不支持并行

小A吃饭吃到一半,电话来了,小A停了下来接了电话,接完后继续吃饭。支持并发

小A吃饭吃到一半,电话来了,小A一边打电话一边吃饭。支持并行

 

------------------------------------------------------------分割线-------------------------------------------------------------------

在面试中我们会碰到这种场景:
面试官:能解释下什么是同步,异步么?

程序员:假如我们执行A,B两个IO操作的时候,如果必须等待A完成后才能执行B那么这个就是

同步的,如果A,B可以同时执行那么就是异步的。

面试官:那能解释下什么是阻塞什么是非阻塞么?

程序员:如果必须等待A完成后才能执行B那么这个就是阻塞的,如果A,B可以同时执行那么就 是非阻塞的

面试官:那你的意思异步/同步的概念与阻塞非阻塞一样了?

程序员:嗄。。。可以这么说吧。我觉得可以并发执行的就是异步非阻塞的。one by one执行 的就是同步阻塞的


二:区分

每个人看去看同一个问题都会有不同的理解,原因就是因为每个人的看待问题的深度不一样,就像上面的对白,程
序员的理解只是停留在应用层面,代码里有多个IO操作,每个IO操作都可以不用互相等待的“同时”执行。

接下来我们就来探讨下异步/同步与阻塞/非阻塞它们其中的区别。

阻塞 / 非阻塞描述的是函数, 指访问某个函数时是否会阻塞线程(block),导致线程进入阻塞状态。
同步 / 异步描述的是执行IO操作的主体是谁,同步是由用户态的进程自己去执行IO操作,异步是用户态进程不关心IO细节,由内核态进程去完成IO操作然后通知用户态进程。

好的,现在定义已经描述完了。现在可以区分它们之间的区别了么?(吃瓜群众:这TM的写的是什么?) ,别急,我们下面举栗说明,包教包会。


三:举栗

一般来说IO分为两个阶段,第一阶段是等待数据阶段,第二阶段是内核空间的数据拷贝到用户空间,假设一个线程(或是进程)P准备执行一个IO操作的话它会经历以下过程:

第一阶段:

P发出一个IO请求,这时候会有两种情况:
1:立刻返回: 非阻塞
2:一直等待,P调用sleep/wait休眠或是挂起,让出CPU给别的线程/进程  阻塞

第二阶段:

这时内核的数据终于准备好了,
那么现在用户进程想要读取内核空间的数据有两种方式:
1:  P自己把数据从内核空间拷贝到用户空间       同步
2:P创建一个线程做数据copy的工作        异步

现在应该明白了吧。阻塞/非阻塞是针对IO的第一阶段的描述。异步/同步是针对IO的第二阶段的描述也就是IO的主体。

这里主要比较难理解的就是同步/异步。首先P在发起IO的请求的时候如果P本身还要负责IO请求后的数据copy(内核空间到用户空间)工作。那么我们就可以说是同步的。

 

如果P在发起IO操作后数据copy的工作由内核线程/进程或是P自己再创建一个线程/进程去完成,那么我们就可以称之为异步


四:排列组合

同步阻塞IO:

  • 同一个线程在操作IO时一直阻塞,直到读取数据成功,然后线程本身负责把数据从核心空间拷贝到用户空间

同步非阻塞:

  • 同一个线程发起IO后,立即获得返回,后面定期轮询数据读取情况,发现数据读取成功,线程本身负责把数据从核心空间拷贝到用户空间

异步非阻塞:

  • 一个线程发起IO后,立即返回,由另外的线程发现数据读取成功,把数据从核心空间拷贝到用户空间。

非阻塞同步IO由于读写方法非阻塞,并且需要用户自己来进行读写,所以每次调用读写方法实际读写的字节数是不确定的,所以需要一个Buffer来保存每次读写的字节状态。更重要的是用户不知道什么时候完成了读写,一般需要用
while循环判断Buffer的状态来跟踪读写。非阻塞异步IO由于是内核线程进行读写,并且在IO完成后会回调用户提供的callback,编程模型就比较简单,用户只需要调用读写,提供回调就可以了,比如 read(filename, callback)select / poll / epoll 从本质上说都是非阻塞同步IO,select会收到IO就绪的状态,然后通知用户去处理

IO,实际的IO操作还需要用户等待内核复制操作。

要理解IO就绪和完成的区别。就绪指的是还需要用户自己去处理,完成指的是内核帮助完成了,用户不用关心IO过

程,只需要提供回调函数。


五:并行/并发与异步

并行

  • 对多处理器而言--多个程序在同一时刻发生,具有并发的含义,但并发不一定并行,也亦是说并发事件之间不一定要同一时刻发生。

  • 并行:在单处理器中多道程序设计系统中,进程被交替执行,表现出一种并发的外部特种;在多处理器系统中,进
    程不仅可以交替执行,而且可以重叠执行。在多处理器上的程序才可实现并行处理。计算机操作系统中把并行性和并发性明显区分开,主要是从微观的角度来说的,具体是指进程的并行性(多处理机的情况下,多个进程同时运行)和并发性(单处理机的情况下,多个进程在同一时间间隔运行的)

并发

对单处理器而言--多个程序在同一时间段发生;

  • 并发中又有:互斥和同步:

    互斥:进程间相互排斥使用临界资源;比如写操作;
    
    同步:不是排斥关系而是依赖关系,前一个进程的输出是后一个进程的输入
    
    当第一个进程没有结束时第二个进程必须等待,相互协同完成一些事情;
    
    具有同步关系的一组进程并发时发送的消息称为消息或者事件;
    
    
  • 同步和异步:

    异步:就是线程B在等待A的结果的时候还可以继续干自己的事儿,
    
    之间通过消息和事件来通知对方,提高了程序运行的效率。
    
    简而言之,就是不是站在那儿傻傻死等;异步和多线程并不是一回事,
    
    异步是最终目的,多线程只是实现的一种方法。

 

 

转自 转自

 

exit(?)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值