GIL操作

想让C扩展代码和Python解释器中的其他进程一起正确的执行, 那么你就需要去释放并重新获取全局解释器锁(GIL)。

在Python接口封装中去释放并重新获取全局解释器锁(GIL),此时本段程序失去GIL运行,其他线程可以无视本函数的运行而运行,直到Py_END_ALLOW_THREADS:

#include "Python.h"
... PyObject *pyfunc(PyObject *self, PyObject *args) {
...
Py_BEGIN_ALLOW_THREADS
// Threaded C code. Must not use Python API functions
...
Py_END_ALLOW_THREADS
...
return result;
}

只有当你确保没有Python C API函数在C中执行的时候你才能安全的释放GIL。 GIL需要被释放的常见的场景是在计算密集型代码中需要在C数组上执行计算(比如在numpy中) 或者是要执行阻塞的I/O操作时(比如在一个文件描述符上读取或写入时)。

当GIL被释放后,其他Python线程才被允许在解释器中执行。 Py_END_ALLOW_THREADS 宏会阻塞执行直到调用线程重新获取了GIL。

C和Python中的线程混用

混合使用C、Python和线程, 有些线程是在C中创建的,超出了Python解释器的控制范围, 并且一些线程还使用了Python C API中的函数时,需要确保正确的初始化和管理Python的全局解释器锁(GIL)。

要想这样,可以将下列代码放到你的C代码中并确保它在任何线程被创建之前被调用:

#include <Python.h>
...
if (!PyEval_ThreadsInitialized()) {
PyEval_InitThreads();
}
...

对于任何调用Python对象或Python C API的C代码,确保你首先已经正确地获取和释放了GIL, 这可以用 PyGILState_Ensure()PyGILState_Release() 来做到,如下所示:

...
/* Make sure we own the GIL */
PyGILState_STATE state = PyGILState_Ensure(); /* Use functions in the interpreter */
...
/* Restore previous GIL state and return */
PyGILState_Release(state);
...

在涉及到C和Python的高级程序中,很多事情一起做是很常见的—— 可能是对C、Python、C线程、Python线程的混合使用。 只要你确保解释器被正确的初始化,并且涉及到解释器的C代码执行了正确的GIL管理,应该没什么问题。

要注意的是调用 PyGILState_Ensure() 并不会立刻抢占或中断解释器。 如果有其他代码正在执行,这个函数被中断知道那个执行代码释放掉GIL。 在内部,解释器会执行周期性的线程切换,因此如果其他线程在执行, 调用者最终还是可以运行的(尽管可能要先等一会)。

『Python CoolBook』C扩展库_其六_线程的更多相关文章

  1. 『Python CoolBook』C扩展库_其一_用法讲解

    不依靠其他工具,直接使用Python的扩展API来编写一些简单的C扩展模块. 本篇参考PythonCookbook第15节和Python核心编程完成,值得注意的是,Python2.X和Python3. ...

  2. 『Python CoolBook』C扩展库_其三_简单数组操作

    点击进入项目 这里的数组要点在于: 数组结构,array.array或者numpy.array 本篇的数组仅限一维,不过基础的C数组也是一维 一.分块讲解 源函数 /* Average values ...

  3. 『Python CoolBook』C扩展库_其五_C语言层面Python库之间调用API

    点击进入项目 一.C层面模块添加API 我们仍然操作如下结构体, #include <math.h> typedef struct Point { double x,y; } Point; ...

  4. 『Python CoolBook』C扩展库_其二_demo演示

    点击进入项目 C函数源文件 /* sample.c */ #include "sample.h" /* Compute the greatest common divisor */ ...

  5. 『Python CoolBook』C扩展库_其四_结构体操作与Capsule

    点击进入项目 一.Python生成C语言结构体 C语言中的结构体传给Python时会被封装为胶囊(Capsule), 我们想要一个如下结构体进行运算,则需要Python传入x.y两个浮点数, type ...

  6. 『Python CoolBook』C扩展库_其六_从C语言中调用Python代码

    点击进入项目 一.C语言运行pyfun的PyObject对象 思路是在C语言中提供实参,传给python函数: 获取py函数对象(PyObject),函数参数(C类型) 获取GIL(PyGILStat ...

  7. 『Python CoolBook』使用ctypes访问C代码_下_demo进阶

    点击进入项目 这一次我们尝试一下略微复杂的c程序. 一.C程序 头文件: #ifndef __SAMPLE_H__ #define __SAMPLE_H__ #include <math.h&g ...

  8. 『Python CoolBook』使用ctypes访问C代码_上_用法讲解

    一.动态库文件生成 源文件hello.c #include "hello.h" #include <stdio.h> void hello(const char *na ...

  9. 『Python CoolBook』Cython

    github地址 使用Cython导入库的话,需要一下几个文件: .c:C函数源码 .h:C函数头 .pxd:Cython函数头 .pyx:包装函数 setup.py:python 本节示例.c和.h ...

随机推荐

  1. 洛谷P4396 作业 [AHOI2013] 莫队

    正解:莫队 解题报告: 传送门! 天呐太久没做莫队了连板子都认不出来了,,,所以复健下做下莫队的题目QAQ 就很板子鸭,和莫队板子比好像只有一个离散化,,,?就不讲了QAQ 等下直接放代码QAQ ov ...

  2. vs自定义类模板

    .找到VS安装目录,我的目录是:C:Program Files (x86)Microsoft Visual Studio 12.0 .在C:Program Files (x86)Microsoft V ...

  3. WIN7无法访问共享打印机及文件的解决办法

    故障: 在网上邻居上能看到对方的电脑名字,双击进入的时候弹出问题.出现“用户账户限制”或“未授予用户在计算机上的请求登陆类型”的问题,这说明我们的局域网和网络是畅通的,问题的根源就在电脑的安全设置上. ...

  4. Cartographer源码阅读(6):LocalTrajectoryBuilder和PoseExtrapolator

    LocalTrajectoryBuilder意思是局部轨迹的构建,下面的类图中方法的参数没有画进去. 注意其中的三个类:PoseExtrapolator类,RealTimeCorrelativeSca ...

  5. 这5个实用技巧,教你设计出更好的App

    三年前,谷歌公司分享了一项研究:用户平均会安装36个app在手机上,但每天都使用的只有9个.据统计,只有4%的app会被使用一年以上. 所以,能运用基本用户体验设计原则来设计出更好的app,对公司大有 ...

  6. HTML5 元素属性介绍

    HTMLElement 表示所有的 HTML 元素. 这里将以事件属性和非事件属性的分类进行介绍. 事件属性大多继承自GlobalEventHandlers,非事件属性大多继承自Element. 菜单 ...

  7. Django的安装

    ##pip pip是Python的包管理工具,用于快速安装配置所需要的拓展包,能够很好的解决包之间的依赖关系 当前ubuntu 系统上有两个Python环境,使用pip3 是指定Python3的环境 ...

  8. Python之__slots__ &运算符重载反向运算

    1.运算符重载之反向运算 class A: def __init__(self,x): self.x = x def __add__(self, other): try: x = other.x re ...

  9. 用javaScript获取页面元素值

    用JavaScript获取页面元素常见的三种方法:                                                           getElementById() ...

  10. 20190404用户及用户组管理(week1_day4)

    useradd userdel usermod groupadd groupdel 用户管理 为什么需要有用户? 1. linux是一个多用户系统 2. 权限管理(权限最小化) 用户:存在的目录是为了 ...