Python线程有问题吗?
一位可靠的编码员朋友告诉我,Python当前的多线程实现存在严重的错误,足以避免完全使用。关于这个谣言该怎么说?
解决方案
回答
我已经在多个应用程序中使用过它,并且从未听说过线程不是100%可靠的东西,只要我们知道它的局限性即可。我们不能同时产生1000个线程,并希望程序在Windows上正常运行,但是我们可以轻松地编写一个工作池并仅对其进行1000次操作,并保持一切正常并受到控制。
回答
据我所知,没有真正的错误,但是由于GIL(全局解释器),在cPython中进行线程处理时的性能确实很差(与大多数其他线程实现相比,但如果所有大多数线程都处于阻塞状态,通常就足够好了)锁定),因此实际上它是实现特定的,而不是语言特定的。例如,Jython不会因为使用Java线程模型而遭受此困扰。
请参阅这篇文章,了解为什么从cPython实现中删除GIL并非真正可行,以及一些实际的阐述和解决方法。
快速搜索" Python GIL"以获取更多信息。
回答
Python线程非常适合并发I / O编程。线程一旦阻塞等待来自文件,网络等的输入,就会被交换出CPU。这允许其他Python线程在其他线程等待时使用CPU。例如,这将允许我们编写多线程Web服务器或者Web搜寻器。
但是,Python线程在进入解释器核心时会被GIL序列化。这意味着,如果两个线程处理数字,则在任何给定时刻只能运行一个。这也意味着我们无法利用多核或者多处理器体系结构。
有一些解决方案,例如使用基于C的线程库同时运行多个Python解释器。这不是为了胆小,利益可能不值得麻烦。让我们希望在将来的版本中提供全Python解决方案。
回答
GIL(全局解释器锁定)可能是一个问题,但是API还是可以的。试用出色的"处理"模块,该模块为单独的进程实现了Threading API。我现在正在使用它(尽管在OS X上,尚未在Windows上进行一些测试),并且给我留下了深刻的印象。在管理复杂性方面,Queue类确实为我节省了培根!
编辑:似乎从2.6版开始,处理模块已包含在标准库中("导入多处理")。喜悦!
回答
Python的标准实现(通常用C语言编写,通常称为CPython)使用OS线程,但是由于具有全局解释器锁,因此一次仅允许一个线程运行Python代码。但是在那些限制内,线程库是健壮的并且被广泛使用。
如果我们希望能够使用多个CPU内核,则有一些选择。如其他人所述,一种方法是同时使用多个python解释器。另一种选择是使用不使用GIL的Python的不同实现。两个主要选项是Jython和IronPython。
Jython用Java编写,尽管有些不兼容之处,但它现在已经相当成熟。例如,Web框架Django尚不能完美运行,但是一直都在接近。 Jython在线程安全性方面非常出色,在基准测试中表现更好,并且为那些需要GIL的人提供了厚脸皮的信息。
IronPython使用.NET框架,并用C#编写。兼容性已达到Django可以在IronPython上运行的阶段(至少作为演示),并且有在IronPython中使用线程的指南。
回答
如果要使用python编写代码并获得强大的线程支持,则可能需要查看IronPython或者Jython。由于IronPython和Jython中的python代码分别在.NET CLR和Java VM上运行,因此它们享受这些库中内置的强大线程支持。除此之外,IronPython还没有GIL,这是阻止CPython线程充分利用多核体系结构的问题。