听说 Python 的多线程是假的,无法利用多核心?

2020-10-27 15:03:43 +08:00
 James369
貌似 js 也是单线程,唉,脚本语言。。

查了一下 python 有一个叫 GIL 的全局锁,本质上无法做到多 CPU 核心的同时利用了?

那我现在有几个重 CPU 的任务,只能用多进程来实现了?还得搞多进程通信。。
5603 次点击
所在节点    Python
31 条回复
coderluan
2020-10-27 15:15:19 +08:00
调 C 的多线程就行, 不要用多进程
coderxy
2020-10-27 16:03:28 +08:00
nodejs 就是无法利用多核心,所以会起多个进程。 不过现在很多都是 k8s 环境下,单个 pod 只利用单核心也没毛病。
James369
2020-10-27 16:28:18 +08:00
@coderluan 怎么调,有相关的包吗
coderluan
2020-10-27 16:28:47 +08:00
@James369 自己搜去, 一搜一堆.
jdhao
2020-10-27 16:31:55 +08:00
你具体什么问题?如果是 io 密集型操作,用 asyncio 或者 threadpoolexecutor 做并发不一定慢,干嘛非得多线程。

或者 cpu 密集操作,多进程做也没问题。
chaleaoch
2020-10-27 16:46:33 +08:00
重 CPU 任务是指计算密集吗?
计算密集你用 python?

node 主线程确实是单线程, 不过 Node 本身自己都承认擅长 IO 不擅长 CPU 计算.

不知道吐槽点在哪里.
em70
2020-10-27 16:48:27 +08:00
我经常 20 个 python 进程跑满 CPU 的,写在一个进程里还麻烦
GrayXu
2020-10-27 16:55:39 +08:00
为什么不好好用搜索引擎呢?

import multiprocessing
est
2020-10-27 16:56:28 +08:00
LZ 恐怕也没听说过几个能用系统内核线程的语言。。。
oahebky
2020-10-27 17:00:04 +08:00
其实 Python 的多进程和多线程差不多好写;

如果你线程间传递数据要考虑加锁,
而进程间传递数据涉及到进程间通信(但是 Python 的库已经封装好了,很容易调用传递数据)

也就是说,你要“并行执行”,其实在 Python 中写线程和进程几乎没有差别。

如果你涉及到并行执行的“东西”要传递数据,只是把线程加锁的思考换成进程间通信的思考,也差不多。


然后如果是那种用 queue 发消息的传递数据类型,在 Python 中进程和线程的写法也是非常像...


所以问题不在于 GIL,

问题在于:
1. programmer 是否理解并发和并行
2. 是否理解 IO 密集和 CPU 密集
3. 是否知道 Python 有 GIL 这个东西
4. programmer 掌握的并发编程「模型」的水平。


而其它语言(比如 golang )好写并发代码(多线程),应该是人家已经给你限定好了一种并发模型,让“入门者”的就照着这么写就好了(恩,我没用过 golang,但是我猜是 golang 这样子的,有不对欢迎指正)。
leavic
2020-10-27 17:06:35 +08:00
所以我直接多进程不就行了
oahebky
2020-10-27 17:07:02 +08:00
对了 “问题在于:” 还要再插入一个点,

“3. 是否理解‘线程内存(变量)共享’ 和 ‘进程内存拷贝’ 之间的区别”。
xiaoshenke
2020-10-27 17:12:04 +08:00
@oahebky 好不好写不关键。进程耗 cpu 。java 来实现开 20 个线程,py 就需要 20 个进程,高下立判
oahebky
2020-10-27 17:25:40 +08:00
@xiaoshenke

你的这种比较在选择了脚本语言 /动态语言的程序员眼里没有意义。

至少在我这边没有意义。

如果说别的语言并行比较好写,我会觉得是优点。

但是如果说别的语言多线程利用 CPU 比 Python 多进程利用 CPU “效率”更高,在我这边没有意义。


因为就是有像我这类开发者并不关心一门语言在机器上的执行速度,而是编程语言的其它方面。


(当然,根据应用的业务场景,语言在机器上的执行速度可能是重要的,
但这是针对业务的技术选型问题,不是编程语言本身的问题;
就像用锤子去敲螺丝,这不是锤子的问题,这是你选择锤子还是选择螺丝刀的问题。)
kkbblzq
2020-10-27 17:26:31 +08:00
@xiaoshenke 所以才说要确定你的业务是不是 CPU 密集型的,调度这块的确线程有优势,但是你长期占满不需要调度的情况下差距就小了
ai277014717
2020-10-27 17:30:21 +08:00
可以用支持利用多核的语言来写然后封装成 cli 或者 libc 来调用。推荐 cli crash 了不会影响父进程。
xiaoshenke
2020-10-27 17:34:57 +08:00
@oahebky 同理 你在比较语言好不好写在我这里也没有意义
chogath
2020-10-27 17:36:40 +08:00
CPU 核心的同时利用还是得用 C,另外 node.js 其实可以使用 worker_threads 模块开启多线程,不过要处理数据共享,我的方案是任务启动前先写入公共 JSON 文件中,线程任务独立地读取 JSON 文件内的数据 /配置并执行任务
acmore
2020-10-27 18:06:37 +08:00
无论多线程多进程协程纤程,本质都是为了提升 CPU 的利用率。如果你要处理的任务是 I/O 密集型的,那么直接用 Python 协程就好了,效率很有可能比多线程或者多进程更高。如果你要处理的任务是计算密集型的,那么 Python 多进程 / C 扩展多线程是更好的选择,当然最好的选择是用其他语言。

另外 JS 是单线程 ≠ JS 只能利用一丢丢计算资源,这里的单线程确切来说是用户能直接操作的是单线程。无论在浏览器还是在 Node 平台上,背后都有一堆工作线程在做事。能最大限度利用资源才是直接和最终的目标。
Meltdown
2020-10-27 19:05:59 +08:00
经常看到你不一定需要真正的多线程这种回答就感觉好窝火🔥

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

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

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

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

© 2021 V2EX