【问题标题】:What's the cost of releasing the GIL?发布 GIL 的成本是多少?
【发布时间】:2011-10-21 23:59:50
【问题描述】:

假设我有一个 C 扩展函数,它做的事情完全独立于 Python 解释器。是否有任何理由发布 GIL?

例如,是否有任何理由不编写这样的代码(除了可读性和避免微优化等问题——这些问题很重要,但与我的问题并不真正相关)?

Py_BEGIN_ALLOW_THREADS
    a = 1 + 1;
Py_END_ALLOW_THREADS

很明显,这是一些琐碎的代码,性能可能不会太重要。但是是否有任何性能原因在此处发布 GIL?还是应该只为更多 CPU 密集型代码发布 GIL?

【问题讨论】:

    标签: python multithreading gil python-c-extension


    【解决方案1】:

    GIL 是一个普通的互斥体。锁定或解锁 uncontested 互斥体的成本极低,不比更改全局变量的成本高多少。但是,如果您经常锁定和解锁有争议的互斥锁,则互斥锁的成本可能会变得很大。

    所以,这通常不是一个好主意:

    Py_BEGIN_ALLOW_THREADS
        a = 1 + 1;
    Py_END_ALLOW_THREADS
    

    这里发生的情况是您正在解锁一个互斥体,然后您会立即尝试再次锁定。如果这是两个大代码块之间的中断,那么它会给另一个线程一个运行的机会。但是如果你对线程粒度没有问题,就保持锁定。

    所以在这种情况下这是一个好主意:

    very_long_computation_requires_gil();
    Py_BEGIN_ALLOW_THREADS;
    a = a + i;
    Py_END_ALLOW_THREADS;
    very_long_computation_also_requires_gil();
    

    在不了解上下文的情况下做出有根据的猜测确实是不可能的,而且如果不运行测试通常仍然很困难。

    【讨论】:

      【解决方案2】:

      如果您有一个完全独立于 Python 解释器的 C 扩展函数,那么释放 GIL 通常是一个好主意。唯一的缺点是等待 GIL 回来。在 Python 3.2 中,您必须等待至少 1/20 秒。

      【讨论】:

        【解决方案3】:

        专家仍在对 GIL 进行调整和测试。

        这是关于旧问题的新想法: inside-look-at-gil-removal-patch

        您也可以考虑尝试 Stackless Python(无 GIL)或 PyPy(带有即时编译器的 Python)。

        【讨论】:

        • 我不明白反对票。我的回答是对最佳讨论的参考,Guido 和其他开发人员在该讨论中比较了有关 GIL 的不同问题和不同解决方案。这里没有任何答案涉及到那种程度的细节和专业知识。
        • 这很简单:您的帖子没有回答问题。 (请注意,不是我投了反对票)
        • Ferdinand,我同意我的链接不是一个完整的答案,但我仍然认为它比其他用户的猜测要好。此外,我建议 Stackless 和 PyPy,它们不是一个实用的答案吗?
        • 你看,OP 知道 GIL 并且可能也知道替代方案。但问题非常具体:使用 CPython 时,在 C 中编写扩展时,经常发布 GIL 是一个好主意还是有缺点?这就是为什么您的答案根本没有用(将其与接受的答案进行比较)。但不要太担心否决票。
        【解决方案4】:

        有什么理由不发布 GIL?

        如果 C 扩展调用不可重入代码,那么如果多个 Python 线程同时调用该扩展,您可能会遇到问题。因此,您可能希望避免在此类扩展中释放 GIL 以防止这种情况发生(当然,您可以在 Python 级别或 C 级别创建自己的互斥锁来实现这一点,而不会影响其他线程)。

        还是应该只为更多 CPU 密集型代码发布 GIL?

        释放 GIL 的另一个主要原因是调用阻塞的 C 扩展(例如套接字上的阻塞读取)以使其他线程能够运行。这正是 Python 解释器本身在线程中执行阻塞操作时发生的情况。

        【讨论】:

          猜你喜欢
          • 2011-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多