Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >深入理解并发/并行,阻塞/非阻塞,同步/异步

深入理解并发/并行,阻塞/非阻塞,同步/异步

作者头像
用户1332428
发布于 2018-03-09 09:15:24
发布于 2018-03-09 09:15:24
1.3K0
举报
文章被收录于专栏:人工智能LeadAI人工智能LeadAI

1、阻塞,非阻塞

首先,阻塞这个词来自操作系统的线程/进程的状态模型中,如下图:

进程状态

一个线程/进程经历的5个状态,创建,就绪,运行,阻塞,终止。各个状态的转换条件如上图,其中有个阻塞状态,就是说当线程中调用某个函数,需要IO请求,或者暂时得不到竞争资源的,操作系统会把该线程阻塞起来,避免浪费CPU资源,等到得到了资源,再变成就绪状态,等待CPU调度运行。

定义: 阻塞调用是指调用结果返回之前,调用者会进入阻塞状态等待。只有在得到结果之后才会返回。 非阻塞调用是指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

阻塞调用:比如 socket 的 recv(),调用这个函数的线程如果没有数据返回,它会一直阻塞着,也就是 recv() 后面的代码都不会执行了,程序就停在 recv() 这里等待,所以一般把 recv() 放在单独的线程里调用。

非阻塞调用:比如非阻塞socket 的 send(),调用这个函数,它只是把待发送的数据复制到TCP输出缓冲区中,就立刻返回了,线程并不会阻塞,数据有没有发出去 send() 是不知道的,不会等待它发出去才返回的。

拓展

如果线程始终阻塞着,永远得不到资源,于是就发生了死锁。

比如A线程要X,Y资源才能继续运行,B线程也要X,Y资源才能运行,但X,Y同时只能给一个线程用(即互斥条件)用的时候其他线程又不能抢夺。

A 有 X,等待 Y。 B 有 Y,等待 X。

于是A,B发生了循环等待,造成死锁。给用户的感觉就是程序卡着不动了。

在写代码的时候要特别注意共享资源的使用,用信号量控制好,避免造成死锁。死锁的解除有个著名的银行家算法(https://baike.baidu.com/item/%E9%93%B6%E8%A1%8C%E5%AE%B6%E7%AE%97%E6%B3%95)

阻塞和挂起:阻塞是被动的,比如抢不到资源。挂起是主动的,线程自己调用 suspend() 把自己退出运行态了,某些时候调用 resume() 又恢复运行。

线程执行完就会被销毁,如果不想线程被频繁的创建,销毁,怎么办?可以给线程里面写个死循环,或者让线程有任务的时候执行,没任务的时候挂起,就像iOS中的 runloop 机制一样。线程就不会随便的终止了。

2、同步、异步

定义 同步:在发出一个同步调用时,在没有得到结果之前,该调用就不返回。 异步:在发出一个异步调用后,调用者不会立刻得到结果,该调用就返回了.

同步例子

int n = func(); next(); // func() 的结果没有返回,next() 就不会执行,直到 func() 运行完。

异步例子

func(callback); next(); ... void callback(int n) // func 结果回调 { int k = n; } // func() 执行后,还没得出结果就立即返回,然后执行 next() 了 // 等到结果出来,func() 回调 callback() 通知调用者结果。

同步的定义看起来跟阻塞很像,但是同步跟阻塞是两个概念,同步调用的时候,线程不一定阻塞,调用虽然没返回,但它还是在运行状态中的,CPU很可能还在执行这段代码,而阻塞的话,它就肯定不在CPU中跑这个代码了。这就是同步和阻塞的区别。同步是肯定可以在,阻塞是肯定不在。

异步和非阻塞的定义比较像,两者的区别是异步是说调用的时候结果不会马上返回,线程可能被阻塞起来,也可能不阻塞,两者没关系。非阻塞是说调用的时候,线程肯定不会进入阻塞状态。

上面两组概念,就有4种组合。

同步阻塞调用:得不到结果不返回,线程进入阻塞态等待。

同步非阻塞调用:得不到结果不返回,线程不阻塞一直在CPU运行。

异步阻塞调用:去到别的线程,让别的线程阻塞起来等待结果,自己不阻塞。

异步非阻塞调用:去到别的线程,别的线程一直在运行,直到得出结果。

3、并发,并行

先从定义说起,定义经过我通俗化了,原定义有点难理解。

并发是指一个时间段内,有几个程序都在同一个CPU上运行,但任意一个时刻点上只有一个程序在处理机上运行。

并行是指一个时间段内,有几个程序都在几个CPU上运行,任意一个时刻点上,有多个程序在同时运行,并且多道程序之间互不干扰。

两者区别如下图:

并行是多个程序在多个CPU上同时运行,任意一个时刻可以有很多个程序同时运行,互不干扰。

并发是多个程序在一个CPU上运行,CPU在多个程序之间快速切换,微观上不是同时运行,任意一个时刻只有一个程序在运行,但宏观上看起来就像多个程序同时运行一样,因为CPU切换速度非常快,时间片是64ms(每64ms切换一次,不同的操作系统有不同的时间),人类的反应速度是100ms,你还没反应过来,CPU已经切换了好几个程序了。

切换耗时:线程用完了时间片,释放CPU控制权,引发系统中断,调度程序根据相关策略选取下一个线程来运行,这里需要一点耗时。

举个例子吧,并行就是,多个人,有人在扫地,有人在做饭,有人在洗衣服,扫地,做饭,洗衣服都是同时进行的。

并发就是,有一个人,这个人一会儿扫地,一会儿做饭,一会儿洗衣服,他在这3件事中来回做,同一时刻只做一件事,不是同时做的,但最后3件事都可以做完。

时间片大小的选取

时间片取的小,假设是20ms,切换耗时假设是 10ms。 那么用户感觉不到多个程序之间会卡,响应很快,因为切换太快了,但是CPU的利用率就低了,20 / (20 + 10) = 66% 只有这么多,33%都浪费了。

时间片取的大,假设是200ms,切换耗时是 10ms 那么用户会觉得程序卡,响应慢,因为要200ms后才轮到我的程序运行,但是CPU利用率就高了,200 / (200 + 10) = 95% 有这么多被利用的。

所以时间片取太大或者太小都不好,一般在 10 - 100 ms 之间。

CPU调度策略

在并发运行中,CPU需要在多个程序之间来回切换,那么如何切换就有一些策略。

3.1 先来先服务-时间片轮转调度

这个很简单,就是谁先来,就给谁分配时间片运行,缺点是有些紧急的任务要很久才能得到运行。

3.2 优先级调度

每个线程有一个优先级,CPU每次去拿优先级高的运行,优先级低的等等,为了避免优先级低的等太久,每等一定时间,就给优先级低的线程提高一个级别。

3.3 最短作业优先

把线程任务量排序,每次拿处理时间短的线程运行,就像我去银行办业务一样,我的事情很快就处理完了,所以让我插队先办完,后面时间长的人先等等,时间长的人就很难得到响应了。

3.4 最高响应比优先

用线程的等待时间除以服务时间,得到响应比,响应比小的优先运行。这样不会造成某些任务一直得不到响应。

3.5 多级反馈队列调度

有多个优先级不同的队列,每个队列里面有多个等待线程。

CPU每次从优先级高的遍历到低的,取队首的线程运行,运行完了放回队尾,优先级越高,时间片越短,即响应越快,时间片大小就不是固定的了。

每个队列的内部还是用先来先服务的策略。

最后发个以前写的模拟CPU调度的程序(下载地址

https://github.com/hehe520/Data-structure-and-algorithm/tree/master/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9B%B8%E5%85%B3%E7%AE%97%E6%B3%95/%E8%BF%9B%E7%A8%8B%E8%B0%83%E5%BA%A6%E5%92%8C%E9%A1%B5%E9%9D%A2%E7%BD%AE%E6%8D%A2%E7%AE%97%E6%B3%95)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-12-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 人工智能LeadAI 微信公众号,前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入理解并发/并行,阻塞/非阻塞,同步/异步
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_35512245/article/details/53836580
大黄大黄大黄
2018/09/14
1.2K0
深入理解并发/并行,阻塞/非阻塞,同步/异步
并发-并行-阻塞-非阻塞-异步-同步-长连接-短连接-进程-线程-协程
并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行。所以无论从微观还是从宏观来看,二者都是一起执行的。
分母为零
2020/05/25
7700
传统同步阻塞和异步非阻塞的区别理解
同步与异步的理解 同步与异步的重点在消息通知的方式上,也就是调用结果通知的方式。 同步:当一个同步调用发出去后,调用者要一直等待调用结果的通知后,才能进行后续的执行。 异步:当一个异步调用发出去后,调用者不能立即得到调用结果的返回。 异步调用,要想获得结果,一般有两种方式: 1、主动轮询异步调用的结果; 2、被调用方通过callback来通知调用方调用结果。
小勇DW3
2019/11/10
1K0
准确理解阻塞、非阻塞、同步、异步
但是你还真别小看这几个基础概念,由于网上的说法五花八门,众说纷纭,导致了不同的人对这几个概念的理解差异还有点大,错误理解和云里雾里的人大有人在。有的人还会把阻塞/非阻塞与同步/异步混合起来理解,认为阻塞=同步、非阻塞=异步。
用户6901603
2024/03/11
1380
准确理解阻塞、非阻塞、同步、异步
深入理解同步和异步、阻塞和非阻塞、并行和串行这几个概念
如果之前有同学看过我的 《我眼中的Java大牛之孤尽老师》 这篇文章,就会发现里面已经提及一二,遗憾的是大多数同学都是遇到问题的时候才想着去问去看。
明明如月学长
2021/11/25
6640
深入理解同步和异步、阻塞和非阻塞、并行和串行这几个概念
并发编程(一)
异步:提交完任务之后不原地等待任务的返回结果,直接去做其他事 ,结果由反馈机制自动提醒(优化)
HammerZe
2022/03/24
2310
并发编程(一)
"女票"竟然问我什么是同步、异步、阻塞、非阻塞?
大家应该看标题就知道了,今天要通过大白话+图形跟我女票(哪里来的女票?假想一下)讲解同步、异步、阻塞、非阻塞、并行、并发的理解。我女票是一个爱问问题的人,最喜欢没事问计算机方面的,尽管她是一名数学教师,尽管她学过计算机编程;但是我认为她啥都不会,有时候在我烦躁的问我,我会冲她发脾气,这里呢,认认真真(当面)跟女票道个歉,她纯粹是想帮我分忧解难。
我是阿沐
2021/06/01
6350
socket阻塞与非阻塞,同步与异步、I/O模型
在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:
用户6280468
2022/03/21
3.4K0
socket阻塞与非阻塞,同步与异步、I/O模型
深入理解--异步和非阻塞同步和阻塞异步和非阻塞
异步和非阻塞的概念实际上已经出现了很长一段时间。但是异步真正开始流行起来,是因为AJAX技术逐渐成为主流的web开发技术。非阻塞的概念真正流行起来,是当java引入NIO,也可以称作非阻塞IO的API,开始走进主流的开发人员的视线,真正流行起来,也可以认为是node.js带来的。
desperate633
2018/08/22
1K0
15分钟读懂进程线程、同步异步、阻塞非阻塞、并发并行,太实用了!
是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。
Bug开发工程师
2020/03/02
8.3K0
python并发编程之多进程理论部分
一 并发与并行   无论是并行还是并发,在用户看来都是'同时'运行的,不管是进程还是线程,都只是一个任务而已,真是干活的是cpu,cpu来做这些任务,而一个cpu同一时刻只能执行一个任务   一 并发:是伪并行,即看起来是同时运行。单个cpu+多道技术就可以实现并发,(并行也属于并发) 二 并行:同时运行,只有具备多个cpu才能实现并行          单核下,可以利用多道技术,多个核,每个核也都可以利用多道技术(多道技术是针对单核而言的)          有四个核,六个任务,这样同一时间有四个任务被执
用户1214487
2018/01/24
8030
python并发编程之多进程理论部分
异步,同步,阻塞,非阻塞程序的实现
终于用透支生命的方法把这一课学完了。感动。以后不这样了。 实现异步非阻塞是一个大命题,这里只从原理出发。我会慢慢修改这篇文章。 本文将从异步sleep的实现入手,来讲解异步非阻塞程序的原理。
超级大猪
2019/11/21
7.8K0
深入理解Java并发编程:并行与并发、进程与线程、优先级、休眠与让步
Java多线程是一种并发编程方式,允许Java应用程序同时执行多个独立任务。它通过创建和管理多个线程来实现,
杨不易呀
2023/09/27
1.4K1
深入理解Java并发编程:并行与并发、进程与线程、优先级、休眠与让步
socket阻塞与非阻塞,同步与异步、I/O模型
在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:
黄规速
2022/04/14
2.5K0
socket阻塞与非阻塞,同步与异步、I/O模型
【进击面试_02】Java 多线程
进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
Demo_Null
2021/03/04
3580
【进击面试_02】Java 多线程
一文为你讲解清楚并发,同步,异步,互斥,阻塞,非阻塞
互斥:同一个资源同一时间只有一个访问者可以进行访问,其他访问者需要等前一个访问者访问结束才可以开始访问该资源。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
Jasonangel
2021/05/28
10K0
Netty系列(六):阻塞/非阻塞、同步/异步的区别
操作系统可以支持多个进程应用同时运行,这就需要保证不同进程间不相互干扰,即一个进程崩溃不会影响其他进程、也不能去扰乱其他进程运行。这就需要操作系统对用户进程进行调度管理,于是内存空间被划分为用户空间和内核空间,用户空间进行数据处理,而对数据读写以及进程调度则由权限更高的内核空间处理。
鳄鱼儿
2024/05/21
3870
Netty系列(六):阻塞/非阻塞、同步/异步的区别
Python--进程
进程:正则进行的一个过程或者说一个任务,而负责执行任务的则是CPU。进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统基础的结构。早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。
py3study
2020/01/19
8780
Java并发编程
单核CPU下,线程实际还是 串行执行 的。操作系统中有一个组件叫任务调度器,将CPU的时间片(windows下时间片最小约为15毫秒)分给不同的程序使用,只是由于CPU在线程间(时间片很短)的切换非常快,人类感觉是 同时运行的 。总结一句话: 微观串行,宏观并行。
Remember_Ray
2020/08/05
8770
操作系统-面试篇
操作系统是管理计算机硬件和软件资源的计算机程序,提供一个计算机用户与计算机硬件系统之间的接口。
知识浅谈
2022/02/21
6910
推荐阅读
相关推荐
深入理解并发/并行,阻塞/非阻塞,同步/异步
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档