나는 제거 할 수없는 segfault를 만드는 아주 잘린 예제가 있습니다. 파이썬 스크립트는 확장 기능에서 C 함수를 호출하여 pthreads를 사용하여 새 스레드를 만듭니다. PyGILState_Ensure 및 PyGILState_Release 내 파이썬 호출 (PyRun_SimpleString) 새 스레드에서 사용하지만, 아마도 제대로 사용하지 않는 또는 다른 단계를 놓친. receive_audio 함수에서 파이썬 호출을 주석 처리하면 더 이상 segfault가 발생하지 않습니다. 어떤 아이디어?Segfault가 멀티 스레드 파이썬 확장 C 언어로
출력 :
파이썬 lib 디렉토리/test.py
(메인 스레드) initmodule 완전한
(메인 스레드)를 호출 run_thread()
(메인 스레드) 만들기 스레드
receive_audio에서 (새 스레드)() - GIL 획득
(새 스레드) python print!
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);
}
}
한 노트 - pthread_create 함수를 호출하는 PyGILState_Ensure() 및 PyGILState_Release 호출은 중요하지 않은 것처럼 보입니다. 나는 그것이 메인 스레드에 의해 실행되고 있기 때문에 기대되는 것이라고 생각한다. – cursemyziti