总结
豆包 AI 助手文章总结

为什么有人说 Python 的多线程是鸡肋呢?

php中文网
发布: 2016-06-06 16:11:12
原创
1817人浏览过

回复内容:

GIL blablabla concurrent blablabla

简单地说就是作为可能是仅有的支持多线程的解释型语言(perl的多线程是残疾,PHP没有多线程),Python的多线程是有compromise的,在任意时间只有一个Python解释器在解释Python bytecode。

UPDATE:如评论指出,Ruby也是有thread支持的,而且至少Ruby MRI是有GIL的。

如果你的代码是CPU密集型,多个线程的代码很有可能是线性执行的。所以这种情况下多线程是鸡肋,效率可能还不如单线程因为有context switch

但是:如果你的代码是IO密集型,多线程可以明显提高效率。例如制作爬虫(我就不明白为什么Python总和爬虫联系在一起…不过也只想起来这个例子…),绝大多数时间爬虫是在等待socket返回数据。这个时候C代码里是有release GIL的,最终结果是某个线程等待IO的时候其他线程可以继续执行。

反过来讲:你就不应该用Python写CPU密集型的代码…效率摆在那里…

如果确实需要在CPU密集型的代码里用concurrent,就去用multiprocessing库。这个库是基于multi process实现了类multi thread的API接口,并且用pickle部分地实现了变量共享。

再加一条,如果你不知道你的代码到底算CPU密集型还是IO密集型,教你个方法:

multiprocessing这个module有一个dummy的sub module,它是基于multithread实现了multiprocessing的API。

假设你使用的是multiprocessing的Pool,是使用多进程实现了concurrency
<span class="kn">from</span> <span class="nn">multiprocessing</span> <span class="kn">import</span> <span class="n">Pool</span>
登录后复制
Global Interpretor Lock 在python的原始解释器CPython中存在着GIL(Global Interpreter Lock,全局解释器锁),因此在解释执行python代码时,会产生互斥锁来限制线程对共享资源的访问,直到解释器遇到I/O操作或者操作次数达到一定数目时才会释放GIL。

所以,虽然CPython的线程库直接封装了系统的原生线程,但CPython整体作为一个进程,同一时间只会有一个获得GIL的线程在跑,其他线程则处于等待状态。这就造成了即使在多核CPU中,多线程也只是做着分时切换而已。

不过muiltprocessing的出现,已经可以让多进程的python代码编写简化到了类似多线程的程度了。 有泳池一个,四个泵,但只有一个人,一人只能开启管理着其中一个,所以四个泵没什么用。
====================================================================
但是,如果泵的工作时间与冷却恢复时间是1:3(感谢inoahx指出,已改),那么配置的利用率高达100%。(这是基于个人理解的一个比喻,如不妥,请补充)。 一般大部分的观点是由于有 GIL 的存在,Python 中的多线程不能真正的利用多核,不能解决 cpu bound 的问题,但是在一些 IO bound 的程序上却可以有很好的提升。
但是目前的情况是 我们有了协程啊,在 2.x 系列里我们可以使用 gevent 啊,在 3.x 系列的标准库里又有了 asyncio 。IO bound 的问题完全可以用协程解决。而且我们可以自主的控制协程的调度了。为什么还要使用由 OS 调度的不太可控的线程呢?
所以我认为线程在 Python 里就是个鸡肋。尤其实在 3.x 系列里。

还有一个介绍 2012 不宜进入的三个技术点(中) @yegle 说的大部分都是对的。
唯有并发 I/O 的一部分…… 为什么会有“线程是为不懂状态机的程序员准备的”这种说法?在单核的计算机上编程根本不需要使用多线程编程吗? 这个问题已经说了我想说的了。
并发 I/O 的情况请善用 Tornado / Gevent 这种基于库,每 CPU 核心起一个进程跑一个 event loop;除非请求的处理时间远大于 I/O 和 job scheduling 的时间,这种情况实际上也应该通过 MQ 往多机上发布任务了。 Python多线程是不是鸡肋,是,GIL那个东西再那里摆着,就算在多核下面Python也是无法并行的,这个好理解嘛,就相当于做了个分时复用。

Python多线程有没有用,有,你去爬图片站的时候,用单进程单线程这种方式,进程很容易阻塞在获取数据socket函数上,多线程可以缓解这种情况。你说解决没有,要是每个请求都阻塞起了,那多线程也没什么用(当然,这种情况没见过哈)。

Python的优势就在于写起来快,用起来方便。你要做计算密集型的,还想并行化的话,还是用C吧。 对于计算密集型的任务,多线程是鸡肋,不如用多进程,但是对于IO密集型的任务,多线程并不是鸡肋,因为网络IO的延迟比CPU的更大。 个人看法,线程本身就是一个有些复杂甚至可以说有些丑陋的解决方案,95%的情况下其实都可以不用——KISS。

如果要用并发处理,基本上使用 非阻塞多路复用+多进程 方式,就可以处理绝大多数需求了
python速学教程(入门到精通)
python速学教程(入门到精通)

python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
豆包 AI 助手文章总结
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号