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

深入理解并发/并行,阻塞/非阻塞,同步/异步
【并发编程】深入理解——阻塞/非阻塞、同步/异步、并发/并行的概念
[并发概念] 同步与异步、阻塞与非阻塞

1. 阻塞,非阻塞

阻塞是关于线程/进程的.

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

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

阻塞调用:比如 socket 的 recv(),调用这个函数的线程如果没有数据返回,它会一直阻塞着,也就是 recv() 后面的代码都不会执行了,程序就停在 recv() 这里等待,所以一般把 recv() 放在单独的线程里调用。
非阻塞调用:比如非阻塞socket 的 send(),调用这个函数,它只是把待发送的数据复制到TCP输出缓冲区中,就立刻返回了,线程并不会阻塞,数据有没有发出去 send() 是不知道的,不会等待它发出去才返回的。

2. 同步, 异步

同步与异步通常用来形容一次调用,关注的是消息通信机制(被调用者是否主动告诉调用者结果)。

同步:同步调用一旦开始,调用者必须等到调用返回后,才能进行后续的行为。(也就是说,被调用者不会主动告诉结果,而是调用者主动等待调用的结果。)
异步:异步调用发出后,调用就会立即返回,告诉调用者我方收到请求已经去处理,调用者可以继续后续的操作。(异步调用的操作通常在另外一个线程内真实的执行,完成后主动通知调用者。)
在这里插入图片描述

3. 同步/异步,阻塞/非阻塞的四种组合

同步与阻塞、异步与非阻塞是比较容易混淆的概念。同步等价于阻塞,异步等价于非阻塞是理解上的误区,是不正确的。

同步阻塞调用:得不到结果不返回,线程进入阻塞态等待。
同步非阻塞调用:得不到结果不返回,线程不阻塞一直在CPU运行。
异步阻塞调用:去到别的线程,让别的线程阻塞起来等待结果,自己不阻塞。
异步非阻塞调用:去到别的线程,别的线程一直在运行,直到得出结果。

例子:

同步阻塞:以烧水壶为例,按下烧水开关之后,我们什么也不做,就一直在那等着,这就叫阻塞;而同步是用来形容水壶的,它不会主动告诉我们结果,需要我们一直盯着水壶是否烧开。
同步非阻塞:非阻塞是指按下烧水开关之后,继续干其他事情。由于是同步的,水壶不会主动告诉我们水是否烧开。因此我们可以每隔几分钟去看下水壶情况。
异步阻塞:异步表示水壶具有提醒功能,发出声音。我们按下烧水开关之后,仍然坐等着,直到水壶发出提醒水烧开,我们将水壶取下来。
异步非阻塞:按下烧水开关后,我们就去干其他事情,听到水壶烧开声音后,取下水壶。

3. 并发,并行

并发与并行是两个相关(related)但不同(distinct)的概念,都是“同时做多件事”

  • 并发关注的点是多件事被同时(一段时期)做,但只有一件事情正在执行(单核)!
  • 并行关注的点是多个“人”在同时做事情。只有多核系统才能实现并行处理。

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

在这里插入图片描述
在这里插入图片描述

5、并发编程的实现方式(多线程/异步编程)

并发,就是同时做多件事情,所以多线程可以实现并发,单线程同样可以实现并发。

好的程序应该能充分利用有限的 CPU 资源,努力提高资源利用率,该需求可以有两种实现途径:

  • 通过多线程/多进程来实现。
  • 异步编程:
    线程/进程是稀缺资源,数量有限,且线程/进程上下文切换成本高。程序中的线程越多,上下文切换的成本越高,CPU 有效利用率越低!另外,在多线程/多进程模型中,需要考虑并发控制的问题,增加了编程的复杂度。
    那么如何实现不依赖多线程/多进程的并发编程呢?此时,异步编程就应运而生了!
    一方面,异步/非租塞通过减少对线程/进程的依赖,提高了 CPU 资源的有效利用率,同时避免了多线程/多进程中并发控制的问题;另一方面,异步编程可以降低编程的复杂度。

系统层面: 进程(Process),线程(Thread)

现代操作系统 Unix/Linux/Windows 都是支持“多任务”的操作系统,为并发编程提供了不同的任务模型——进程,线程,程序员可以借助多线程+多进程来实现并发编程。

线程是最小的执行单元,而进程由至少一个线程组成,线程/进程调度,如何时执行,执行多久,由操作系统来决定。数据共享和并发控制是多线程/多进程编程时面临的重要挑战,增加了编程的复杂度;另外,频繁的上下文切换,也会影响 CPU 的使用效率。

为了减少线程切换,会使用线程池来管理线程。

语言层面(异步编程): Channel,Coroutine(协程),Futures and Promises

并发编程的灵活度会极大的影响一门编程语言的表现力,比如:

  • Python 中的协程、async/wait,
  • C# 中的 Task,async/wait,
  • Go 中的 Channel。
  • 另外 future, promise, delay, deferred 也是编程语言中并发编程模型相关的术语。
Python 协程(coroutine)

协程能向多线程一样并发执行,但是避免了线程切换,所以执行效率很高。另外,因为协程之间是同步执行了,不需要像多线程编程那样进行并发控制,不需要加锁,所以比多线程编程简单。

  • 函数调用是通过调用栈来实现的,有一个入口,有一个返回值,调用顺序是明确的。
  • 但是协程不同,协程允许先中断、并跳转到其它地方执行,并在适当的时候返回来继续执行。
    在这里插入图片描述
Python async/await

从 Python 3.5 开始引入了新的语法 async 和 await,可以让 coroutine(协程) 的代码更简洁易读。

import asyncio as aio

async def hello():
	print("Hello World")
	r = await asyncio.sleep(100) # 耗时 io
	print("Hello again!")

loop = aio.get_event_loop()
tasks = [hello(), hello()] # 初始化任务(其实就是创建 coroutine 对应的 generator)
loop.run_until_complete(aio.wait(tasks))
loop.close()

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
同步非阻塞异步非阻塞是两种不同的函数调用方式。 同步非阻塞是指在发起函数调用后,调用方不会等待函数的结果返回,而是立即继续执行后续的代码。这意味着调用方无需等待函数的执行结果,可以继续处理其他任务。当函数执行完毕后,调用方可以通过轮询或者回调等方式来获取函数的结果。同步非阻塞的优点是能够提高系统的并发性和响应性。 异步非阻塞是指在发起函数调用后,调用方也不会等待函数的结果返回,但是与同步非阻塞不同的是,异步非阻塞会通过回调、事件通知等方式来通知调用方函数的执行结果。调用方可以继续执行其他任务,并在合适的时机处理函数的返回结果。异步非阻塞的优点是能够提高系统的并发性和性能,减少资源的浪费。 总结来说,同步非阻塞异步非阻塞都是在函数调用时不会发生线程阻塞的情况下继续执行后续代码,但区别在于同步非阻塞需要主动轮询或回调来获取函数的结果,而异步非阻塞则通过回调或事件通知等方式传递函数的执行结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [深入理解同步阻塞同步非阻塞异步阻塞异步非阻塞](https://blog.csdn.net/wangpaiblog/article/details/117236684)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值