27

一位可靠的程序员朋友告诉我,Python 当前的多线程实现存在严重错误 - 足以完全避免使用。这个谣言能说什么呢?

4

6 回答 6

58

Python 线程非常适合并发 I/O 编程。一旦线程阻塞等待来自文件、网络等的输入,线程就会从 CPU 中换出。这允许其他 Python 线程在其他线程等待时使用 CPU。例如,这将允许您编写多线程 Web 服务器或 Web 爬虫。

但是,Python 线程在进入解释器核心时会被GIL序列化。这意味着如果两个线程正在处理数字,那么在任何给定时刻只有一个线程可以运行。这也意味着您无法利用多核或多处理器架构。

有一些解决方案,例如使用基于 C 的线程库同时运行多个 Python 解释器。这不适合胆小的人,而且好处可能不值得麻烦。让我们希望在未来的版本中有一个全 Python 的解决方案。

于 2008-08-29T06:33:54.780 回答
16

Python 的标准实现(通常称为 CPython,因为它是用 C 编写的)使用 OS 线程,但由于有Global Interpreter Lock,一次只允许一个线程运行 Python 代码。但是在这些限制范围内,线程库是健壮的并且被广泛使用。

如果您希望能够使用多个 CPU 内核,有几个选项。一种是同时使用多个python解释器,正如其他人所提到的。另一种选择是使用不使用 GIL 的不同 Python 实现。两个主要选项是JythonIronPython

Jython 是用 Java 编写的,现在已经相当成熟,但仍然存在一些不兼容性。例如,网络框架Django 还没有完美运行,但一直在接近。Jython非常适合线程安全在基准测试中表现更好,并且对于那些想要 GIL 的人来说是一个厚颜无耻的信息。

IronPython 使用 .NET 框架并用 C# 编写。兼容性达到了Django 可以在 IronPython 上运行的阶段(至少作为演示),并且有在 IronPython 中使用线程的指南

于 2008-08-29T17:17:18.527 回答
9

GIL(全局解释器锁)可能是个问题,但 API 还不错。试试这个优秀的processing模块,它为单独的进程实现了线程 API。我现在正在使用它(尽管在 OS X 上,尚未在 Windows 上进行一些测试)并且印象深刻。Queue 类在管理复杂性方面确实节省了我的培根!

编辑:从 2.6 版(import multiprocessing)开始,处理模块似乎已包含在标准库中。喜悦!

于 2008-08-29T06:55:14.103 回答
5

据我所知,没有真正的错误,但是由于GIL(全局解释器),cPython 中的线程性能非常糟糕(与大多数其他线程实现相比,但如果所有线程都阻塞,通常就足够了) Lock),所以它实际上是特定于实现而不是特定于语言的。例如,由于使用 Java 线程模型,Jython 就不会受到这种影响。

请参阅这篇文章,了解为什么从 cPython 实现中删除 GIL 并不可行,以及一些实际的详细说明和解决方法。

快速搜索“Python GIL”以获取更多信息。

于 2008-08-29T05:58:34.833 回答
2

如果您想在 python 中编写代码并获得出色的线程支持,您可能需要查看 IronPython 或 Jython。由于 IronPython 和 Jython 中的 python 代码分别在 .NET CLR 和 Java VM 上运行,因此它们享受这些库中内置的出色线程支持。除此之外,IronPython 没有 GIL,这是一个阻止 CPython 线程充分利用多核架构的问题。

于 2009-02-23T06:15:07.290 回答
-2

我已经在几个应用程序中使用过它,并且从来没有听说过线程不是 100% 可靠的,只要你知道它的限制。您不能同时产生 1000 个线程并期望您的程序在 Windows 上正常运行,但是您可以轻松编写一个工作池并为其提供 1000 个操作,并保持一切正常并处于可控状态。

于 2008-08-29T05:50:47.817 回答