Python线程何时运行速度快?

11
我们都知道GIL的恐怖,我看到很多关于使用multiprocessing模块的讨论,但我仍然不觉得自己对Python中的线程(主要是CPython)何时是正确答案有很好的直觉。
在哪些情况下GIL不是一个重大瓶颈?哪些类型的用例是线程最合适的选择?
4个回答

14

如果有很多阻塞I/O操作,使用线程才有意义。在这种情况下,一些线程可以睡眠,而其他线程则可以工作。如果线程受限于CPU,则不太可能从多线程中获得多少好处。

请注意,multiprocessing模块虽然编码更加困难,但利用了单独的进程,因此不会受到GIL的缺点的影响。


我同意Michael的答案。线程足以处理简单的网络操作、从用户那里收集输入或在后台执行某些工作时更新GUI表单。我经常用它来完成这些任务。我想为这个答案补充的是我的多进程模块使用经验。我几乎不使用这个模块。每次我想使用它,那就意味着我需要长时间使用全部CPU资源。所以我开始思考如何优化这个问题,最终我编写了一个C/C++模块来处理所有关键的多线程代码。 - Zuljin
即使在多核机器上,也只能同时执行一个线程。这是CPython中全局解释器锁(GIL)的结果。@mklauber - Michael Mior
@Michael Mior,你说得完全正确,我完全混淆了GIL。现在正在编辑/删除不正确的评论。 - mklauber
认为在一些io密集型任务的情况下,使用multiprocessing比线程更合适是合理的吗?我认为,在某些情况下,上下文切换的开销与GIL引起的开销相比,并不会那么糟糕。 - mvanveen
1
如果你有大量的I/O绑定线程,其中几个将在任何特定时间被解除阻塞,那么是的。实际上,找出最好的方法是测量 :) - Michael Mior

10

看起来你在寻找一些例子,以下是我能想到和从搜索CPU和I/O限制的例子中获得的。请注意,我不是专家,请随时更正我分类错误的内容。同时也值得注意的是,先进的技术可能会将问题从一类移动到另一类。

CPU Bound 任务(使用 multiprocessing

  • 数学函数的数值方法/近似(计算圆周率等)
  • 图像处理
  • 执行卷积
  • 为图形编程计算变换(可能由GPU处理)
  • 音频/视频压缩/解压缩

I/O Bound 任务(threading 可能可行)

  • 通过网络发送数据
  • 写入/读取磁盘
  • 请求用户输入
  • 音频/视频流

2

GIL(全局解释器锁)防止Python运行多个线程。

如果您的代码在进入C扩展之前释放了GIL,则其他Python线程可以在C代码运行时继续运行。就像其他人提到的阻塞IO一样。

Ctypes会自动执行此操作numpy也是如此。因此,如果您的代码经常使用它们,可能不会受到GIL的显着限制。


0
除了CPU绑定和I/O绑定任务之外,还有更多的用例。例如,线程使并发任务成为可能。许多GUI编程都属于这一类别。主循环必须对鼠标事件做出响应。因此,每当您有一个需要花费一段时间且不想冻结UI的任务时,可以在单独的线程上执行它。这与性能关系较小,而与并行性关系更大。

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