如何检查线程当前是否包含GIL?

时间:2012-07-06 16:59:16

标签: python multithreading gil

我试图找到一个函数,告诉我当前线程是否具有全局解释器锁。

Python / C-API文档似乎没有包含这样的功能。

我目前的解决方案是使用PyGILState_Ensure()获取锁定,然后使用PyEval_SaveThread释放锁定,以免尝试释放当前线程未获取的锁定。

(顺便说一句。"发出致命错误"是什么意思?)

这个问题的背景:我有一个嵌入Python的多线程应用程序。如果线程在没有释放锁定的情况下关闭(可能由于崩溃而发生),则其他线程将无法再运行。因此,在清理/关闭线程时,我想检查该线程是否保持锁定,并在这种情况下释放它。

提前感谢您的回答!

2 个答案:

答案 0 :(得分:10)

如果您正在使用(或可以使用)Python 3.4,那么有一个新功能用于完全相同的目的:

if (PyGILState_Check()) {
    /* I have the GIL */
}

https://docs.python.org/3/c-api/init.html?highlight=pygilstate_check#c.PyGILState_Check

  

如果当前线程持有GIL则返回1,否则返回0。可以随时从任何线程调用此函数。只有当它的Python线程状态已初始化并且当前持有GIL时它才会返回1.这主要是辅助/诊断功能。例如,当知道GIL被锁定时,它可以在回调上下文或内存分配函数中有用,可以允许调用者执行敏感操作或以其他方式表现不同。

在python 2中,您可以尝试以下内容:

int PyGILState_Check2(void) {
    PyThreadState * tstate = _PyThreadState_Current;
    return tstate && (tstate == PyGILState_GetThisThreadState());
}

在我尝试的案例中似乎运作良好。 https://github.com/pankajp/pygilstate_check/blob/master/_pygilstate_check.c#L9

答案 1 :(得分:2)

我不知道你在找什么...但是你应该考虑使用这两个宏Py_BEGIN_ALLOW_THREADSPy_END_ALLOW_THREADS,用这些宏你可以确保它们之间的代码没有没有锁定GIL,并确保随机崩溃。