2012-10-02 5 views
1

멀티 쓰레드와 함께 boost.python C/C++ 프로그램을 개발합니다.()Boost python/thread에서 모듈을 가져 오려면 ReleaseLock()이 필요합니다. 왜?

PyEval_InitThreads; main()에서

, I는 스레드를 생성

pthread_create (& id, & detached_attr, newThread, NULL);

· newThread()에서 두 개의 Py_ * 함수를 호출합니다.

Py_Initialize();

PyGILState_STATE gstate = PyGILState_Ensure();

은 그 때 나는 newThread()hoge()라는 이름의 C++ 함수를 호출 :

void hoge(){ 
    py::object main_module; 
    py::object main_namespace; 

    try { 
     main_module = py::import("__main__"); //segmentation fault 
     main_namespace = main_module.attr("__dict__"); 
    } catch (py::error_already_set const &) { 
     PyErr_Print(); 
    } 

    //Some boost python code 
} 

gdb를 다시 추적 출력이 여기에있다.

(gdb) bt 
#0 0x4032fe24 in __ctype_b_loc() from /lib/libc.so.6 
#1 0x4032fde8 in __ctype_b_loc() from /lib/libc.so.6 

import()이 실패하는 이유는 무엇입니까? 나는 모른다. 이 문제를 해결하는 방법을 알려주십시오. --edit 12/12/28



은 ---

나는 다음과 같은 방법을 사용하여이 문제를 해결했다. main()에서

, 나는

Py_Initialize(); 
PyEval_InitThreads(); 
PyEval_ReleaseLock(); 

가 그럼 난 새로운 스레드를 만들 실행합니다. 새로운 스레드, 나는
PyGILState_STATE gstate = PyGILState_Ensure(); 
CALL SOME PYTHON CODE 
PyGILState_Release(gstate); 

을 실행하지만 지금 왜 작동 나는 을 모른다. 누군가 이유를 말해 줄 수 있니?

+1

더 간단한 예를 먼저 시도하는 것이 좋습니다. 예를 들어 코드없이 스레드없이 실행되도록하십시오. 모든 것이 예상대로 작동하면 (테스트 해보십시오!) 멀티 스레딩을 시도하십시오. –

+0

조언 해 주셔서 감사합니다. 이 문제를 해결할 수 있습니다. – fantajista

+0

어떻게 문제를 해결 했습니까? 나는 같은 문제를 겪고있다 .. –

답변

0

파이썬은 다른 인터프리터 언어와 마찬가지로 두 개의 파이썬 인터프리터 호출이 동시에 작동하지 않도록 전역 인터프리터 잠금 (GIL)을 사용하여 스레드 안전성 (see this wiki)을 구현합니다. 따라서, 파이썬 호출은 먼저 잠금을 요청하고 명령을 실행 한 다음 잠금을 해제해야합니다. 당신은 그 규칙을 따라야 만합니다. 그렇지 않으면 예에서했던 것처럼 통역사가 추락 할 수 있습니다. 함수 hoge()이 GIL을 요청하지 않았으므로 충돌이 발생했습니다.

GIL 요청 (또는 "보장")으로 코드를 래핑하고 함수 호출을 해제해도 문제가 해결되지 않는다면, 여전히 스레드가 두 개인 경우 모두에 액세스 할 수 있어야합니다. GIL. 주 스레드에서 GIL을 풀지 않았다면 실제로 파이썬 파일을 처리하는 두 번째 스레드는 영원히 차단 될 것입니다! 너 그거 해봤 니? 그렇지 않다면, 당신은 단지 어떻게되는지를 볼 수 있습니다.

올바른 해결 방법 - 스스로 찾은 해결책은 모든 스레드에서 GIL을 가져 와서 해제하고 다른 스레드가 굶어 죽는 동안 GIL이있는 스레드 중 하나에 걸리지 않도록해야합니다.

관련 문제