调用Py_Finalize with threads时出现断言错误(仅限3.X)

2024-04-25 01:06:29 发布

您现在位置:Python中文网/ 问答频道 /正文

当我从与python调用不同的C线程调用C-API的Py_Finalize()时,会得到一个错误输出。在

我看到的错误是:

Exception ignored in: <module 'threading' from 'C:\\Python34-32\\Lib\\threading.py'>
Traceback (most recent call last):
  File "C:\Python34-32\Lib\threading.py", line 1289, in _shutdown
    assert tlock.locked()
AssertionError:

这只发生在python3.X(用3.4.2测试)中,在python2.7中完全相同的代码没有任何问题。在

下面是一个最小的示例,它显示了在使用C线程时发生的情况,但不是所有事情都发生在单个C线程上时:

^{pr2}$

输出

--Starting Basic--
--Basic Complete--
--Starting With Thread--
Exception ignored in: <module 'threading' from 'C:\\Python34-32\\Lib\\threading.py'>
Traceback (most recent call last):
  File "C:\Python34-32\Lib\threading.py", line 1289, in _shutdown
    assert tlock.locked()
AssertionError:
--With Thread Complete--

main中basic()/with_thread()调用的顺序无关紧要,我甚至可以多次包含这些行而不受影响,每个with_thread()调用都会导致错误输出。在

编辑:

使threadState全局化,然后将exec更改为:

void exec()
{
   //PyGILState_STATE gstate = PyGILState_Ensure();
   PyEval_RestoreThread(threadState); 
   PyObject* pdict = PyDict_New();
   PyDict_SetItemString(pdict, "__builtins__", PyEval_GetBuiltins());

   PyRun_String("import my_test", Py_file_input, pdict, pdict);
   PyRun_String("my_test.my_function()", Py_file_input, pdict, pdict);
   assert(!PyErr_Occurred());
   //PyGILState_Release(gstate);
   threadState = PyEval_SaveThread();
}

导致错误消失,但是我有一个全局值,我需要在库的用户之间进行协调(在我的实际代码中,exec()函数可以由任何人编写,而且我运行的初始化内容要多得多)。有什么见解可以让GIL抓取更孤立,就像原来的例子一样,同时保持线程兼容性?在


Tags: inpymylib错误assert线程exec