【问题标题】:When are Python threads fast?Python线程什么时候快?
【发布时间】:2012-01-24 21:28:18
【问题描述】:

我们都知道GIL 的可怕之处,我也看到了很多关于使用multiprocessing 模块的正确时机的讨论,但我仍然不觉得我有一个好的关于何时在 Python 中进行线程(主要关注 CPython)的直觉是正确的答案。

在哪些情况下 GIL 不是重大瓶颈?线程是最合适的答案的用例类型有哪些?

【问题讨论】:

    标签: python multithreading gil


    【解决方案1】:

    线程只有在你有很多阻塞 I/O 的情况下才有意义。如果是这种情况,那么一些线程可以在其他线程工作时休眠。如果线程受 CPU 限制,您可能不会从多线程中看到太多好处。

    请注意,multiprocessing 模块虽然更难编写代码,但它使用单独的进程,因此不会受到 GIL 的不利影响。

    【讨论】:

    • 我同意迈克尔的回答。例如,线程足以用于简单的网络操作、从用户那里收集输入或在后台执行某些工作时更新 GUI 表单。我经常将它用于此类任务。我想为这个答案添加的是我对多处理模块的经验。我几乎不使用这个模块。每次我想使用它时,这意味着我需要更长时间的完整 CPU 能力。所以我开始思考如何优化它,最后我为 python 编写了 C/C++ 模块。在这个 C/C++ 模块中,我放置了所有关键的多线程代码。
    • @mklauber 即使在多核机器上,一次也只能执行一个线程。这是 CPython 中全局解释器锁 (GIL) 的结果。
    • @Michael Mior,你完全正确,我完全混淆了 GIL。现在编辑/删除不正确的评论。
    • 是否有理由认为在某些情况下一组 io-bound 任务更适合multiprocessing over threading?我认为在某些情况下,与 GIL 造成的开销相比,上下文切换的开销并没有那么糟糕。
    • @mvanveen 如果您有大量 I/O 绑定线程,其中几个线程将在任何特定时间被解除阻塞,那么可以。真的,找出答案的最好方法是测量:)
    【解决方案2】:

    由于您似乎在寻找示例,因此这里有一些是我脑海中浮现的,是从搜索 CPU 密集型和 I/O 密集型示例中获取的(我似乎找不到很多)。我不是专家,所以请随时纠正我错误分类的任何内容。还值得注意的是,先进的技术可能会将问题从一个类别转移到另一个类别。

    CPU 绑定任务(使用multiprocessing

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

    I/O 绑定任务(threading 可能没问题)

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

    【讨论】:

      【解决方案3】:

      GIL 阻止 python 运行多个线程。

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

      Ctypes does this automaticallyso does numpy。因此,如果您的代码大量使用它们,则可能不会受到 GIL 的显着限制。

      【讨论】:

        【解决方案4】:

        除了 CPU 密集型和 I/O 密集型任务之外,还有更多用例。例如,线程启用并发任务。很多 GUI 编程都属于这一类。主循环必须响应鼠标事件。因此,每当您有一项需要一段时间的任务并且您不想冻结 UI 时,您都可以在单独的线程上执行它。它不是关于性能,而是更多关于并行性。

        【讨论】:

          猜你喜欢
          • 2014-06-10
          • 1970-01-01
          • 1970-01-01
          • 2014-05-03
          • 1970-01-01
          • 1970-01-01
          • 2014-12-10
          • 2011-10-27
          • 1970-01-01
          相关资源
          最近更新 更多