Python是否支持多处理器/多核编程?

70

多处理器编程和多核编程有什么区别?

最好能在Python中展示如何编写小型的多处理器编程和多核编程程序的示例。

7个回答

97

“多处理器”或“多核心”编程并不存在。在应用程序员看来,“多处理器”和“多核心”计算机的区别可能与你无关; 它涉及核心如何共享访问内存的微妙之处。

为了利用多核(或多处理器)计算机,需要编写能够以并行方式运行的程序,并使用运行时使程序实际上可以在多个核心上并行执行(以及操作系统,尽管任何可以在 PC 上运行的操作系统都可以这样做)。这真正是并行编程,尽管有不同的并行编程方法。对于Python相关的是多进程和多线程。

在像 C、C++、Java 和 C# 这样的语言中,可以通过执行多个线程编写并行程序。CPython 和 PyPy 运行时中的全局解释器锁排除了此选项;但仅适用于这些运行时。(我的个人意见是,多线程是危险而棘手的,Python鼓励您不要考虑它作为获取性能优势的一种方式,这通常是件好事。)

如果想在 Python 中编写可以在多个核心上运行的并行程序,则有几种不同的选项:

  • 使用threading模块编写多线程程序,并在 IronPython 或 Jython 运行时中运行它。
  • 使用processing模块(现在包括在 Python 2.6 中的multiprocessing模块)一次性在多个进程中运行代码。
  • 使用subprocess模块运行多个Python解释器并在它们之间通信。
  • 使用TwistedAmpoule。这不仅可以在不同的进程之间运行代码,而且如果您不共享诸如文件之类的访问权限,还可以潜在地在不同的计算机之间运行代码。
  • 无论选择哪种方法,您都需要了解如何将程序正在执行的任务分解成有意义的小块进行分离。由于我不确定您打算编写什么样的程序,因此很难提供一个有用的示例。


    3
    “没有‘多处理器’或‘多核’编程”这种说法是不正确的 - 当然存在。“多核”编程指的是编写能够利用多个核心的应用程序。 - johndodo
    1
    与利用多个处理器的应用程序相反? - Glyph
    9
    这些是多处理器应用程序...不确定我是否表达清楚。我想说的是:大多数人都知道“多核编程”和“多处理器编程”的术语的含义。所以,这个问题可以翻译成“是否可以在Python上编写能够运行在多个核心/处理器上的程序?”你提到的术语是无效的 - 实际上它们是有效的。这就是我想要补充的。 - johndodo
    2
    抱歉,但我不同意你的线程观点。使用线程确实需要一些思考和适当的设计,但我们应该是知道如何思考和解决问题的程序员。是的,可能会糟糕地使用它们,但几乎我们所做的每件事都是如此。为什么要忽略一个需要思考才能使用的工具呢?多个进程并不相同。设置/拆除开销大,浪费内存,通信开销大,如果您想使用无法被pickled的对象,祝您好运。哦,没错,只需围绕限制重新设计您的应用程序即可。 - Basic
    7
    线程编程并不需要特别的思考,当然所有编程都需要思考。线程编程的问题在于,需要在每行代码中时刻注意线程的存在。相比之下,如果你使用消息传递进行编程,可以在函数完结并且准备接收下一条消息之前忘记外部系统的一切。共享可变状态的多线程编程会给程序员带来持续的、严重的焦虑或对用户来说是一连串难以再现的问题。 - Glyph
    显示剩余2条评论

    24

    正如在另一篇文章中提到的那样,Python 2.6拥有multiprocessing模块,它可以利用多个核心/处理器(通过透明地启动多个进程来绕过GIL)。 它提供了与线程模块类似的某些原语。 在文档页面中会找到一些(简单)使用示例。


    这种回答令人惊讶,因为进程不共享它们的地址空间,这导致了一个显著不同的编程模型。 - Alex Kreimer
    这里有一个小而清晰的教程,介绍如何使用Python进行线程编程:https://pythonprogramming.net/threading-tutorial-python/ - Chris McCowan

    5
    您可以编写使用多个处理器的程序。由于GIL锁的存在,您无法使用线程来完成此操作,但可以使用不同的进程来实现。 以下是两种方法:

    1
    线程和Python将在多个核心上分裂,但其中一些核心(除非您在C中进行某些魔法)只会等待GIL。这就是为什么在Python 3.2之前,CPU绑定线程在单核心机器上表现更佳而不是多核心机器的原因。 - Chad
    1
    一些模块是用C实现的,并且会释放GIL。其中之一是zlib模块(也被gzip模块使用)。您可以在Python中使用多个线程来解压缩或压缩数据以利用多个核心。标准库中存在其他示例(如re正则表达式库),还有一些第三方库,例如net-snmp等。 - Will Pierce
    @WillPierce 这段话的意思是“这可以做到,而且非常好,但前提是你不能使用Python”。我可以编写一个C模块,供几乎任何语言使用。这对于C来说是一个优点,但也突显了Python的缺陷。 - Basic

    3

    如果我理解正确,Python 有一个称为 GIL(全局解释器锁)的东西,它在使用多个线程时有效地使利用多核变得不可能。

    参见 Guido van Rossum 的博客文章。据我所知,在“主流”语言中,只有 C/C++ 和 Java 有效支持多核。


    1
    全局解释器锁也只是CPython的问题 - Jython和IronPython分别使用其运行时的线程系统。 - VolkA
    然而,Jython比CPython慢。IronPython的速度与CPython相同。 - Blaisorblade
    @1800INFORMATION 不仅仅是 Windows 用户/开发者经常使用,但这并不适用于 C/C++ 和 Java。句号。 - All Іѕ Vаиітy
    @Marty,我不知道你所说的“主流”是什么意思,但它非常受欢迎。 - 1800 INFORMATION

    2

    1

    主要的区别在于如何组织和分配数据。多核通常在CPU的不同核之间具有更高的带宽,而多处理器需要更多地涉及CPU之间的总线。

    Python 2.6已经拥有了多进程(进程即运行的程序)以及更多用于多线程编程的同步和通信对象。


    0

    如果你没有Python 2.6(例如,如果你使用Ubuntu Edgy或Intrepid),你可以使用Google code backported 版本的multiprocessing。它是PyPI的一部分,这意味着你可以使用EasyInstall(在Ubuntu中是python-setuptools软件包的一部分)轻松安装它。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接