2012-03-05 6 views
4

SWIG을 사용하여 타사 C++ 패키지를 Python 응용 프로그램에 통합하려고합니다. 이 패키지는 네트워크를 통해 독점 API에 연결하고 업데이트를 수신합니다. 전반적인 흐름은 파이썬이 C++ 객체를 인스턴스화하고 함수를 호출하여 설정 한 다음 업데이트를 기다리는 것입니다.SWIG C++ Python 다형성 및 멀티 스레딩

SWIG's directors feature을 사용하여 업데이트를위한 콜백 메커니즘을 구현했으며 Python 또는 Python에서 호출하는 C++ 함수에서 테스트하는 동안 올바르게 작동합니다. 즉, 파이썬에서 C++ 클래스를 상속하고 C++에서 가상 함수를 호출하고 파이썬 코드가 우선 순위를 갖고 실행되는지 확인할 수 있습니다.

문제 : 콜백 함수를 호출하는 동안

The thread 'Win32 Thread' (0x1f78) has exited with code 0 (0x0). 
Unhandled exception at 0x1e0650cb in python.exe: 0xC0000005: Access violation writing location 0x0000000c. 

이 예외가 python27.dll 내에서 발생합니다 :
내가 얻을 네트워크에서 업데이트를받을
. 업데이트가 해당 스레드를 사용하여 다른 스레드와 전화 파이썬의 코드에서 온 나는 GIL
AFAIU을 위반 한:
내 의심이있다.

이 시점에서 나는 실망합니다. SWIG의 디렉터 기능은 파이썬에서 시작된 플로우 (즉, 파이썬 관리 스레드)에서만 제한됩니까?
어떻게 우회합니까? C++에서 Python으로 업데이트를 유도하려면 어떻게해야합니까? 그것은 심지어 SWIG를 사용하여 가능합니까?
전혀 다른 접근 방식을 사용해야합니까? 나는이 문제에 대한 어떤 제안에 열려있어

...

+0

[이 게시물은 SWIG 메일 링리스트] //article.gmane.org/gmane.comp.programming.swig/5306/match=multi+threading+python)이 문제에 대해 정확히 이야기하고 SWIG에서 해결하는 것과 관련된 조치를 요구합니다. 나는 이것이 2004 년 이후 처리 된 적이 없다고 생각한다. – Jonathan

답변

2

당신 꿀꺽 꿀꺽 포장 된 C++ 코드에서 스레드 콜백 루틴을 호출하면, 아마 더 GIL 문제가있어 없습니다 - 꿀꺽 꿀꺽 생성 된 코드가 수행 내가 본 GIL 관리를 수행하지 않습니다. 즉, 파이썬 코드가 C++ 코드를 호출 할 때 호출하는 동안 GIL을 유지합니다.

그러나 C++ 코드가 다른 스레드의 콜백을 연기하면 GIL을 위반했을 가능성이 큽니다. 이것은 간단합니다. 콜백을 호출하기 전에 PyGILState_Ensure()를 호출하고, 콜백이 완료되면 PyGILState_Release를 호출하십시오. http://docs.python.org/c-api/init.html, "Non-Python created threads"섹션을 참조하십시오. (여기서 C++ 예외 처리를 사용하는 경우 GIL을 해제 할 수 있도록 특별히주의해야 할 수도 있습니다.)

아직 스택 추적을 확인하지 않은 경우 NULL을 확인하는 것이 좋습니다 포인터 deref는 바보 같은 일이 코드에서 일어나지 않습니다. (당신은 VS/GDB/WinDBG로 코드를 실행하는 파이썬 프로세스에 연결할 수 있으며 파이썬 실행은 이해할 수 없지만이 방법으로 C++ 코드를 추적 할 수 있습니다.)

+0

SWIG 디렉터를 사용한다면, 다른 스레드/프로세스가 콜백을 트리거하는 경우 직접 GIL을 잠글 필요가 있다는 것을 발견했다. – AndyG