|
5 | 5 | ----------
|
6 | 6 | 问题
|
7 | 7 | ----------
|
8 |
| -You have C extension code in that you want to execute concurrently with other threads |
9 |
| -in the Python interpreter. To do this, you need to release and reacquire the global in‐ |
10 |
| -terpreter lock (GIL). |
| 8 | +你想让C扩展代码和Python解释器中的其他进程一起正确的执行, |
| 9 | +那么你就需要去释放并重新获取全局解释器锁(GIL)。 |
11 | 10 |
|
12 | 11 | |
|
13 | 12 |
|
14 | 13 | ----------
|
15 | 14 | 解决方案
|
16 | 15 | ----------
|
17 |
| -In C extension code, the GIL can be released and reacquired by inserting the following |
18 |
| -macros in the code: |
19 |
| - |
20 |
| -#include "Python.h" |
21 |
| -... |
22 |
| - |
23 |
| -PyObject *pyfunc(PyObject *self, PyObject *args) { |
24 |
| - ... |
25 |
| - Py_BEGIN_ALLOW_THREADS |
26 |
| - // Threaded C code. Must not use Python API functions |
27 |
| - ... |
28 |
| - Py_END_ALLOW_THREADS |
29 |
| - ... |
30 |
| - return result; |
31 |
| -} |
| 16 | +在C扩展代码中,GIL可以通过在代码中插入下面这样的宏来释放和重新获取: |
| 17 | + |
| 18 | +:: |
| 19 | + |
| 20 | + #include "Python.h" |
| 21 | + ... |
| 22 | + |
| 23 | + PyObject *pyfunc(PyObject *self, PyObject *args) { |
| 24 | + ... |
| 25 | + Py_BEGIN_ALLOW_THREADS |
| 26 | + // Threaded C code. Must not use Python API functions |
| 27 | + ... |
| 28 | + Py_END_ALLOW_THREADS |
| 29 | + ... |
| 30 | + return result; |
| 31 | + } |
32 | 32 |
|
33 | 33 | |
|
34 | 34 |
|
35 | 35 | ----------
|
36 | 36 | 讨论
|
37 | 37 | ----------
|
38 |
| -The GIL can only safely be released if you can guarantee that no Python C API functions |
39 |
| -will be executed in the C code. Typical examples where the GIL might be released are |
40 |
| -in computationally intensive code that performs calculations on C arrays (e.g., in ex‐ |
41 |
| -tensions such as numpy) or in code where blocking I/O operations are going to be per‐ |
42 |
| -formed (e.g., reading or writing on a file descriptor). |
43 |
| -While the GIL is released, other Python threads are allowed to execute in the interpreter. |
44 |
| -The Py_END_ALLOW_THREADS macro blocks execution until the calling threads reacquires |
45 |
| -the GIL in the interpreter. |
| 38 | +只有当你确保没有Python C API函数在C中执行的时候你才能安全的释放GIL。 |
| 39 | +GIL需要被释放的常见的场景是在计算密集型代码中需要在C数组上执行计算(比如在numpy中) |
| 40 | +或者是要执行阻塞的I/O操作时(比如在一个文件描述符上读取或写入时)。 |
| 41 | + |
| 42 | +当GIL被释放后,其他Python线程才被允许在解释器中执行。 |
| 43 | +``Py_END_ALLOW_THREADS`` 宏会阻塞执行直到调用线程重新获取了GIL。 |
| 44 | + |
0 commit comments