J'ai un exemple très réduit qui crée une erreur de segmentation dont je n'arrive pas à me débarrasser. Le script Python appelle une fonction C dans une extension, ce qui crée un nouveau thread à l'aide de pthreads. J'utilise PyGILState_Ensure et PyGILState_Release autour de mon appel python (PyRun_SimpleString) dans le nouveau thread, mais peut-être que je ne les utilise pas correctement ou que j'ai manqué une autre étape. Commenter les appels python dans la fonction receive_audio, la segfault ne se produit plus. Des idées?Segfault en extension python multithread en C
Sortie:
python lib/test.py
(thread principal) InitModule complet
(thread principal) Appel run_thread()
(thread principal) Création fil
(Nouveau fil) En receive_audio() - acquisition de GIL
(Nouveau sujet) python print!
(Nouveau fil) Dans receive_audio() - publié GIL
(Nouveau fil) Looping 0
Segmentation fault
code C comme suit:
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);
}
}
Une note - les appels PyGILState_Ensure() et PyGILState_Release autour de la fonction pthread_create semblent être sans conséquence. Je pense que c'est normal car il est géré par le thread principal. – cursemyziti