Python 的多线程原来不是真的多线程啊

2019-11-20 10:33:19 +08:00
 vcfghtyjc

用了好几年 Python 今天第一次知道 Python 的多线程其实是顺序执行各个线程。真正并发还是要靠多进程,或者通过 Cython 调用 C/C++ 的库。

总的来说就是每个线程都需要获取 GIL 后才能执行。具体可以看链接

除了这个以外,各位还有什么在 Python 里踩过的坑吗?可以交流一下。

13102 次点击
所在节点    Python
55 条回复
dbow
2019-11-20 11:30:33 +08:00
GIL 保证解释器同时只解释一个 py 线程的代码, 但是如果这个线程 IO 阻塞了, 解释器就跳到其它线程。 多线程是真的, 只不过锁太大。
dbow
2019-11-20 11:31:55 +08:00
@vcfghtyjc #19 不要用 multiprocess 里的消息传递, 性能挫的一比, 还不如用 redis。
claymore94
2019-11-20 11:33:01 +08:00
其他语言的多线程不也是一个核上只有一个线程在运行么?
vcfghtyjc
2019-11-20 11:33:53 +08:00
@guokeke 问题是 python 的标准库不能用多线程来利用多核
ipwx
2019-11-20 11:35:21 +08:00
@vcfghtyjc 因为你没有指定场景,我们假设是 web app。这种环境不需要 cross process message passing,mp 够了。其次,这种场景基本都是 io,所以其实连 python 多线程也能并发。
当然你可以补充说明一下你的应用场景。
vcfghtyjc
2019-11-20 11:36:22 +08:00
@claymore94 应该不是吧,单进程多线程是可以跑在所有核上的
ipwx
2019-11-20 11:37:29 +08:00
@vcfghtyjc 这真的要看场景。比如我主线程运行 tensorflow session.run ,由于它内部会释放 gil,那我就可以在另一个标准 Python 线程里面,用 python 代码预读下一个 minibatch 的数据。你认为这是不是真的多线程并行?
vcfghtyjc
2019-11-20 11:38:47 +08:00
@ipwx 确实按照通常来讲 web app 是最常见的场景。但是我这里的场景是进 /线程间高通信,高计算,低 IO。
est
2019-11-20 11:39:04 +08:00
@vcfghtyjc 你倒是可以举个例子看看别的语言如何利用多核?

还不是照样加锁。只是人肉在代码里加而已。
ipwx
2019-11-20 11:43:50 +08:00
@vcfghtyjc 高计算场景纯 python 一开始就 out 了,根本连谈论多线程的资格都没有。带 c 库的(比如 numpy, pandas),或者上 cython/numba/pytorch/tensorflow 的,内部都会释放 gil。另外你 mp 库总得用个 c 库的吧,比如 mpi 之类的。一堆 c 库和 io 加持,多线程有啥问题?
ipwx
2019-11-20 11:45:15 +08:00
@vcfghtyjc 而且这种计算,多线程通讯一般都是 c 库内部处理的,干 python 啥事。上多机多卡,python io 和 c 库 io 就又没区别了
trustbutverify
2019-11-20 11:46:04 +08:00
Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once.
ipwx
2019-11-20 11:46:37 +08:00
所以总结一下,python 世界的 c 库比你想象的多,表现形式也比你想象的多。去看看 numba,基本原理是通过 jit 把 Python 代码编译成本机代码。
msg7086
2019-11-20 11:52:04 +08:00
数据共享和多线程并行本来就是冲突的概念。

多线程下多个线程会同时访问同一块内存、同一堆对象,所以必然要对这些区域加锁,加锁就导致线程无法并行。
多进程可以满血并行,但是就会出现你说的进程之间通信开销过高的问题。

换句话说,8 个核心访问同一个变量会 GIL,8 个核心访问 8 个单独的变量副本会带来通信开销。
wuwukai007
2019-11-20 11:57:17 +08:00
走网络或者数据库的,瓶颈不在 cpu,开线程蛮快的
ryd994
2019-11-20 12:03:10 +08:00
Gil 是 CPython 才有的。你用其他 Python runtime 不一定有
vcfghtyjc
2019-11-20 12:11:26 +08:00
@ipwx 那如果想用 Python 实现 parallelism 有什么推荐的库吗?
jdhao
2019-11-20 12:28:46 +08:00
多线程和并行不是一个概念,一个 cpu 一个核也可以多线程
superrichman
2019-11-20 12:31:31 +08:00
有 gil 在,多线程效率上不去,要最大化利用资源还是搞 asyncio 加多进程。最近迷上了 asyncio,啥都想用异步来写。
BingoXuan
2019-11-20 14:19:07 +08:00
python 的 thread 是标准的 posix 线程,你不能因为不能用多核心就说人家不是多线程。超线程技术实际也是通过充分利用 cpu 资源来模拟多个线程而已。

如果你要做到并行计算且数据不共用情况下,直接开多个子进程运行任务就好了。如果你要共用数据进行并行计算,还是用专门计算库,如 cuda。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/621285

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX