我有一个非常精简的示例,它创建了一个似乎无法摆脱的segfault。Python脚本在扩展中调用一个C函数,该函数使用pthreads创建一个新线程。在新线程中,我在python调用(PyRun_SimpleString)中使用PyGILState_sure和PyGILState_Release,但可能我没有正确使用它们,或者错过了其他一些步骤。在receive_audio函数中注释掉python调用,segfault不再发生。有什么想法吗?在
输出:
python库/测试.py
(主线程)initmodule完成
(主线程)调用run_Thread()
(主线程)创建线程
(新线程)在receive_audio()-获取GIL
(新线程)python打印!
(新线程)在receive_audio()-发布的GIL
(新线程)循环0
分段故障
C代码如下:PyMODINIT_FUNC streamaudio() {
PyObject *m = Py_InitModule("streamaudio", methods);
PyEval_InitThreads();
mainThreadState = PyThreadState_Get();
PyEval_ReleaseLock();
printf("(Main Thread) initmodule complete\n");
}
static PyObject* run_thread(PyObject* self, PyObject* args)
{
int ok, stream_id;
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
ok = PyArg_ParseTuple(args, "i", &stream_id);
PyRun_SimpleString("print '(Main Thread) Creating thread'\n");
int rc = pthread_create(&thread, NULL, receive_audio, (void*)stream_id);
PyRun_SimpleString("print '(Main Thread) Thread created'\n");
PyGILState_Release(gstate);
return Py_BuildValue("i", rc);
}
void* receive_audio(void *x)
{
printf("(New Thread) In receive_audio() - acquiring GIL\n");
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
PyRun_SimpleString("print '(New Thread) python print!'\n");
PyGILState_Release(gstate);
printf("(New Thread) In receive_audio() - released GIL\n");
int i;
for (i = 0; i < 100; i++) {
printf("(New Thread) Looping %d\n", i);
sleep(1);
}
}