Python 3.x PythonC扩展是否像对IO任务一样为CPU任务释放GIL?

Python 3.x PythonC扩展是否像对IO任务一样为CPU任务释放GIL?,python-3.x,python-c-api,Python 3.x,Python C Api,在进行IO系统调用时,Python C扩展总是通过Py_BEGIN_ALLOW_线程来释放GIL。对于C扩展是否为运行时间相对较长的CPU受限任务释放GIL,我读到了各种不同的观点。我已经读到python解释器中的CPU受GIL约束,但C扩展中的CPU通常会释放GIL。我假设这样做是安全有效的,只要CPU任务可以在具有细粒度锁定的临时变量中执行,并且GIL是在对共享结构进行更新之前获取的 我在Github的3.6C代码中搜索了所有Py_BEGIN_ALLOW_线程的实例。我可能错过了一些,但在我

在进行IO系统调用时,Python C扩展总是通过Py_BEGIN_ALLOW_线程来释放GIL。对于C扩展是否为运行时间相对较长的CPU受限任务释放GIL,我读到了各种不同的观点。我已经读到python解释器中的CPU受GIL约束,但C扩展中的CPU通常会释放GIL。我假设这样做是安全有效的,只要CPU任务可以在具有细粒度锁定的临时变量中执行,并且GIL是在对共享结构进行更新之前获取的

我在Github的3.6C代码中搜索了所有Py_BEGIN_ALLOW_线程的实例。我可能错过了一些,但在我看来,PythonC扩展通常不会为CPU限制的任务释放GIL

pythoncextensions是否像对IO任务一样,为CPU任务释放GIL

下面是我看到的唯一一个例子,他们确实为CPU任务释放了GIL:

有一个宏ENTER_HASHLIB,带有一条注释,指示它将在CPU消耗HASHLIB操作周围释放GIL

似乎在CPU操作之前允许线程

似乎在CPU操作之前允许线程

我找不到任何其他CPU调用来释放GIL,我肯定可能错过了一些,如果我错过了,请告诉我

例如:

没有Py\u BEGIN\u ALLOW\u线程

没有Py\u BEGIN\u ALLOW\u线程

没有Py\u BEGIN\u ALLOW\u线程

没有Py\u BEGIN\u ALLOW\u线程。

好吧,numpy会这样做,尽管他们在它周围包装了自己的宏NPY\u BEGIN\u ALLOW\u THREADS/NPY\u END\u ALLOW\u THREADS

根据报告:

此组用于调用可能需要一些时间但不使用任何Python C-API调用的代码。因此,GIL应在其计算过程中释放

因此,只有在不使用任何Python C-API调用的情况下,才可以释放GIL。另一种说法是,如果您不访问Python对象


但是您链接的最后四个扩展模块中的代码充满了C-API调用。因此,在那些不涉及C-API调用的模块中,可能没有足够的计算用C来完成,因此释放和重新获取GIL是值得的。

随着GIL的释放,扩展模块无法安全地访问Python对象,因为这将允许另一个线程从它下面更改这些对象。例如,json模块基本上除了读取或创建Python对象之外什么都不做,没有足够长的时间来释放GIL。另一方面,hashlib主要是从一个不可变的str/bytes对象读取数据,其他线程无法对此进行干预。@jasonharper:你应该回答这个问题,而不仅仅是一个注释!