Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中多线程python扩展中的Segfault_Python_Multithreading - Fatal编程技术网

C中多线程python扩展中的Segfault

C中多线程python扩展中的Segfault,python,multithreading,Python,Multithreading,我有一个非常精简的示例,它创建了一个我似乎无法摆脱的segfault。Python脚本在扩展中调用一个C函数,该扩展使用pthreads创建一个新线程。我在新线程中使用PyGILState_sure和PyGILState_Release来处理python调用(PyRun_SimpleString),但可能我没有正确使用它们,或者错过了其他步骤。注释掉receive_audio函数中的python调用后,segfault不再发生。有什么想法吗 输出: python库/test.py (主线程)初始

我有一个非常精简的示例,它创建了一个我似乎无法摆脱的segfault。Python脚本在扩展中调用一个C函数,该扩展使用pthreads创建一个新线程。我在新线程中使用PyGILState_sure和PyGILState_Release来处理python调用(PyRun_SimpleString),但可能我没有正确使用它们,或者错过了其他步骤。注释掉receive_audio函数中的python调用后,segfault不再发生。有什么想法吗

输出:

python库/test.py
(主线程)初始化模块完成
(主线程)调用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);
    }
}
PyMODINIT_FUNC streamaudio(){
PyObject*m=Py_InitModule(“streamaudio”,方法);
PyEval_InitThreads();
mainThreadState=PyThreadState_Get();
PyEval_ReleaseLock();
printf(“(主线程)initmodule complete\n”);
}
静态PyObject*运行线程(PyObject*self,PyObject*args)
{
int ok,流的id;
皮吉州;
gstate=PyGILState_sure();
ok=PyArg\u语法元组(args,“i”和流\u id);
PyRun_SimpleString(“打印(主线程)创建线程”\n”);
int rc=pthread_create(&thread,NULL,receive_audio,(void*)stream_id);
PyRun_SimpleString(“打印(主线程)线程已创建”\n”);
Pygilu状态释放(gstate);
返回Py_BuildValue(“i”,rc);
}
void*接收音频(void*x)
{
printf(“(新线程)在receive_audio()-获取GIL\n”);
皮吉州;
gstate=PyGILState_sure();
PyRun_SimpleString(“打印”(新线程)python打印!”\n);
Pygilu状态释放(gstate);
printf(“(新线程)在receive_audio()-released GIL\n”中);
int i;
对于(i=0;i<100;i++){
printf(“(新线程)循环%d\n”,i);
睡眠(1);
}
}

我不确定这是否与您的问题相关,但有一件看起来可疑的事情是模块初始值设定项函数中的PyEval_ReleaseLock()调用。我怀疑Python是否期望您的模块初始值设定项将GIL从其下面释放出来,而快速查看一些示例代码并没有显示出这方面的任何内容。能否尝试删除PyEval_ReleaseLock()调用并告诉我们发生了什么


顺便说一句,我同意run_thread()中的PyGILState_*()调用应该没有效果;您应该能够删除它们。

注意,围绕pthread_create函数的PyGILState_sure()和PyGILState_Release调用似乎无关紧要。我认为这是意料之中的,因为它是由主线程运行的。很好!成功了。我从这里开始编写代码:他的示例是在C中嵌入python,而我做的是相反的,所以这个调用是灾难性的。谢谢