I have a very stripped-down example that creates a segfault that I cannot get rid of. The Python script calls the C function in the extension, which creates a new thread using pthreads. I am using PyGILState_Ensure and PyGILState_Release around my python call (PyRun_SimpleString) in a new thread, but maybe I am not using them correctly or skipped some other step. Commenting out python calls in the receive_audio function, segfault no longer occurs. Any ideas?
Conclusion:
python lib / test.py
(Main topic) initmodule complete
(Main thread) Call run_thread ()
(Main topic) Creating a thread
(New Topic) In receive_audio () - receiving GIL
(New Topic) python print!
(New Topic) In receive_audio () - GIL released
(New Topic) Looping 0
Segmentation error
C The code is as follows:
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); } }
source share