

Python 与 Go 之间的并发模式差异
source link: https://ceresca.github.io/posts/concurrency-model-differences-between-python-go/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Python并发方式⌗
在 Python 中,早期并发方式以传统的多进程和多线程为主,类似 Java,同时,有不少第三方的异步方案(gevent/tornado/twisted 等)。
在 Python 3 时期,官方推出了 asyncio 和 async await 语法,作为 Python 官方的协程实现,而逐渐普及。
进程⌗
多进程编程示例:
from multiprocessing import Process
def f(name):
print('hello', name)
if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()
multiprocessing 与 threading 的 API 接近,比较容易创建多进程的程序,是 Python 官方推荐作为绕过多线程 GIL 限制的一种方案。
但需要注意,创建进程的参数需要能被 pickle 序列化,最好使用 Pipe、Queue 等进程安全的数据结构(官方文档的 Programming guidelines)
线程⌗
多线程代码示例:
from threading import Thread
def f(name):
print('hello', name)
if __name__ == '__main__':
p = Thread(target=f, args=('bob',))
p.start()
p.join()
# 线程池方式
with ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(pow, 323, 1235)
print(future.result())
Cpython 线程的缺陷:GIL(全局解释器锁)
GIL 是 Cpython 执行 Python 字节码时的一把全局锁,导致解释器在 CPU 密集型任务时不能充分利用多核,而 IO 密集型任务会释放 GIL。
如果想绕过 GIL,只能换成多进程方式,或者通过C 扩展绕过。
协程⌗
asyncio示例:
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
print(f"started at {time.strftime('%X')}")
await asyncio.gather(say_after(1, 'hello'), say_after(2,'world'))
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
# started at 22:32:23
# hello
# world
# finished at 22:32:25
async 语法 与 asyncio⌗
Python 从 3.4 版本开始,标准库自带 asyncio 模块,并从 3.5 开始,支持 async/await 语法。
Python 协程的实现可以追溯到 Python 2 时期引入的 yield 关键字和生成器这种特殊结构:
- 生成器通过 yield 暂停,并且可以返回值
- 调用方通过 next() 或者 send() 方法恢复生成器的运行,并且可以通过 send() 发送数据给生成器
- yield from 语法糖可以方便的迭代生成器中每一个值
- 通过引入 async/await 语法,正式确立协程类型
- asyncio 库提供了官方的事件循环实现,并且支持不同操作系统的 io 多路复用(select/epoll/iocp 等),或者可以通过配置替换为第三方实现(如 uvloop)
- 借助 concurrent.futures 线程池/进程池 模块,支持多线程/多进程,但事件循环本身依旧是单线程模式
Go 并发方式⌗
goroutine 与 channel 示例:
package main
import "fmt"
func main() {
messages := make(chan string)
go func() { messages <- "ping" }()
msg := <-messages
fmt.Println(msg)
}
goroutine 与 channel⌗
Golang 实现了用户态的协程 goroutine,通过GPM模型来进行协程的调度,
并且通过 netpoller 来支持网络的IO多路复用;
通过 channel 在不同 goroutine 中进行通信。
CSP⌗
CSP(通信顺序进程)是一种并发的模型,通过消息传递来进行交互,而不是通过共享变量。
对比⌗
有栈协程与无栈协程⌗
单线程与多线程⌗
Recommend
-
15
by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=1709
-
5
作者:Gbolahan Olagunju译者:前端小智来源:blog有梦想,有干货,微信搜索 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。本文 GitHub
-
7
从 TikTok“重 QA 轻测试”来看中美软件开发之间的差异Tina核子可乐2022...
-
6
Spark和Hadoop之间的主要技术差异和选择 Hadoop 和 Spark 都是开源软件的集合,由 Apache 软件基金会维护,用于大规模数据处理。Hadoop 是两者中较老的一个,曾经是处理大数据的首选。然而,自从 Spark 推出以来,它的增长速度远快于
-
6
← 之前似乎没人想过:天然气里除甲烷外的物质是否对人有害?majer @ 2022.07.04 , 20:27
-
11
Windows和SQL Server身份验证之间的差异 译文 作者: ...
-
6
AMD否认锐龙7000在Win 11和Win10之间性能有差异|amd|处理器|win10|windows|台式机_网易订阅 AMD前几天发表了一份声明,声明驳斥了有关Ryzen 7000在游戏时在Wi...
-
4
EA 和平台架构之间的哲学差异? 解道Jdon ...
-
10
Bootstrap和Tailwind CSS之间的差异? 解道Jdon ...
-
6
AMD阐明Ryzen 1系列与7040U系列之间的差异:优化了电压曲线,禁用AI引擎
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK