파이썬 인터프리터를 멀티 스레드 C 응용 프로그램에 임베드하고 스레드 안전성을 보장하기 위해 사용해야하는 API에 대해 다소 혼란 스럽습니다.멀티 스레드 C 응용 프로그램에 파이썬 포함하기
파이썬을 임베드 할 때 다른 파이썬 C API 호출을 호출하기 전에 GIL 잠금을 처리하는 것이 임베드에 달려 있습니다. 이것은 다음과 같은 기능으로 수행됩니다 :
gstate = PyGILState_Ensure();
// do some python api calls, run python scripts
PyGILState_Release(gstate);
그러나 이것만으로는 충분하지 않습니다. 파이썬 API에 대한 상호 배제를 제공하지 않는 것 같기 때문에 여전히 임의의 충돌이 발생합니다. 바로 Py_IsInitialized()
호출 후
PyEval_InitThreads();
하지만 혼란 부분은 오는 곳이다 :
나는 또한 추가 좀 더 문서를 읽은 후.초기화를 글로벌 인터프리터가
이이 함수가 반환이의 GIL가 가정 할 때 잠을 어떻게 든 잠금을 해제해야한다고 제안 잠금 획득 : 워드 프로세서는이 기능을 것을 주장. 실제로는 이것이 필요하지는 않습니다. 이 라인을 제 자리에 놓으면 멀티 스레드가 완벽하게 작동하고 상호 배제는 PyGILState_Ensure/Release
함수에 의해 유지됩니다.
PyEval_ReleaseLock()
을 PyEval_ReleaseLock()
다음에 추가하려고 시도하면 PyImport_ExecCodeModule()
에 대한 후속 호출에서 앱이 매우 빠르게 데드 록킹됩니다.
그래서 내가 무엇을 놓치고 있습니까?
이것은 잘못되어 잠재적으로 위험합니다 :'PyEval_SaveThread'는 항상'PyEval_RestoreThread'와 함께 있어야합니다. 다른 곳에서 설명 된 것처럼 (http://stackoverflow.com/a/15471525/1600898) 초기화 후에 잠금을 해제하려고하면 안됩니다. Python에 그대로 두어 정규 작업의 일부로 릴리스하십시오. – user4815162342
파이썬에 대한 모든 호출을 _Block_ _Allow_ 블록에 넣으면 왜 위험한 지 알 수 없습니다. 반면,'PyEval_SaveThread();'를 호출하지 않으면 주 스레드가 파이썬에 대한 다른 스레드의 액세스를 차단합니다. 다른 말로하면'PyGILState_Ensure()'교착 상태입니다. – khkarens
이것은 파이썬을 임베딩하고 확장 모듈을 호출하는 데 모두 작용하는 유일한 것입니다. –