2011-12-17 5 views
0

a project에 boost :: python 및 콜백 기반 실행과 관련된 문제가 있습니다.boost :: python 및 콜백 구동 실행

내 프로젝트는 콜백 메커니즘을 사용하여 C++에서 일부 파이썬 코드를 실행합니다.

내 콜백 실행을 유발하는 초기 함수 호출이 파이썬 인터프리터에서 오는 한 모든 것이 정상입니다. 예 :

h = CallbackHandler() 

def mycallback(): 
    print "yeah" 

h.setCallback(mycallback) 

h.runCallback() 

# will print yeah 

아아, 그렇게 간단하지 않습니다. 내 프로젝트에서는 오디오 환경과 통신하기 위해 RtAudio을 사용합니다. RtAudio의 실행은 콜백으로 구동됩니다. 저는 RtAudio에 콜백 함수를 제공하고, RtAudio를 시작할 때마다 사운드를 계산할 때마다 콜백이 호출됩니다.

RtAudio의 콜백 기반 실행을 사용할 때 코드가 C++에서 파이썬 콜백을 실행하려고하면 바로 segfault가 발생합니다.

콜백 구동 실행을 시작하려면 비 블로킹 인 start() 함수를 호출해야합니다. 즉, 콜백에 의한 실행은 다른 스레드에서 발생합니다.

그렇다면 파이썬에서 start()를 호출 할 때 파이썬의 실행 환경에 별도로 액세스하는 다른 스레드를 만들고 있습니다. 파이썬의 GIL에 대한 나의 작은 이해에서 이것은 좋지 않습니다.

그래서이 콜백 위주의 스레드가 모든 것을 망가지지 않고 파이썬 콜백을 실행하도록하려면 어떻게해야합니까?

죄송합니다. 내 문제의 전체 기능을 간략하게 설명하기 위해 코드를 단순화하는 방법을 찾지 못했습니다 ... the problem is located there.

:

편집

python documentation에 둘러보고 후, 나는 비 파이썬 스레드가 파이썬 환경에 액세스하려고 만들 때 스레드 안전을 처리 해야하는 몇 줄의 코드를 추가

gstate = PyGILState_Ensure(); 
while (!queue.empty() && queue.top()->next <= now) { 
    queue.top()->run(); 
    queue.pop(); 
} 
PyGILState_Release(gstate); 

하지만 여전히 세그 폴트가 발생합니다. 그래서 Valgrind의를 통해 실행하고, 여기에 내가 무엇을 얻을 것입니다 (마이너스 이상한 물건 Valgrind의 항상 "정상"인 파이썬 인터프리터에서 얻는다) : 내가 할 경우

==31836== Thread 2: 
==31836== Invalid read of size 4 
==31836== at 0x41F0DD5: [email protected]@GLIBC_2.1 (in /lib/libpthread-2.14.1.so) 
==31836== by 0x5ED294C: callback(void*, void*, unsigned int, double, unsigned int, void*) (in /home/tom/Code/pyck/pyck/libcore.so) 
==31836== by 0x5F6B16B: RtApiAlsa::callbackEvent() (in /usr/lib/librtaudio.so) 
==31836== by 0x5F6BBCC: alsaCallbackHandler (in /usr/lib/librtaudio.so) 
==31836== by 0x42D286D: clone (in /lib/libc-2.14.1.so) 
==31836== Address 0x0 is not stack'd, malloc'd or (recently) free'd 
==31836== 
==31836== 
==31836== Process terminating with default action of signal 11 (SIGSEGV) 
==31836== Access not within mapped region at address 0x0 
==31836== at 0x41F0DD5: [email protected]@GLIBC_2.1 (in /lib/libpthread-2.14.1.so) 
==31836== by 0x5ED294C: callback(void*, void*, unsigned int, double, unsigned int, void*) (in /home/tom/Code/pyck/pyck/libcore.so) 
==31836== by 0x5F6B16B: RtApiAlsa::callbackEvent() (in /usr/lib/librtaudio.so) 
==31836== by 0x5F6BBCC: alsaCallbackHandler (in /usr/lib/librtaudio.so) 
==31836== by 0x42D286D: clone (in /lib/libc-2.14.1.so) 
==31836== If you believe this happened as a result of a stack 
==31836== overflow in your program's main thread (unlikely but 
==31836== possible), you can try to increase the size of the 
==31836== main thread stack using the --main-stacksize= flag. 
==31836== The main thread stack size used in this run was 8388608. 
==31836== 
==31836== HEAP SUMMARY: 
==31836==  in use at exit: 2,313,541 bytes in 2,430 blocks 
==31836== total heap usage: 22,140 allocs, 19,710 frees, 22,007,627 bytes allocated 
==31836== 
==31836== LEAK SUMMARY: 
==31836== definitely lost: 522 bytes in 5 blocks 
==31836== indirectly lost: 0 bytes in 0 blocks 
==31836==  possibly lost: 66,669 bytes in 1,347 blocks 
==31836== still reachable: 2,246,350 bytes in 1,078 blocks 
==31836==   suppressed: 0 bytes in 0 blocks 
==31836== Rerun with --leak-check=full to see details of leaked memory 
==31836== 
==31836== For counts of detected and suppressed errors, rerun with: -v 
==31836== Use --track-origins=yes to see where uninitialised values come from 
==31836== ERROR SUMMARY: 2703 errors from 196 contexts (suppressed: 83 from 13) 

그것은 바로, 내 콜백 함수는 NULL 포인터를 액세스하려고?

편집 2

좋아, 나는 모든이를 발견하고있다. pthread's documentation에서 sem_post(sem)에 대한 호출이있는 것처럼 보입니다. 여기서 sem은 세마포를 가리 킵니다. 하지만 거기 그것은 NULL을 가리 킵니다.

이제 어떻게하면 오류를보다 정확히 찾아 낼 수 있습니까?

+0

valgrind에서 프로그램을 실행하여 문제의 원인을 더 자세히 진단하십시오. –

+0

@ 존 : valgrind 결과 추가 – girodt

+0

제 생각 엔 세마포어 문제는 사용중인 큐의 구현 버그입니다. – Omnifarious

답변

0

나는 GIL에 맞서고 있다고 생각합니다. 내 생각에 콜백 코드는 파이썬 인터프리터로 들어가기 전에 GIL을 얻지 못한다.

GIL을 사용하려고하는 모든 스레드가 GIL을 수행하기 전에 등록해야 할 수도 있습니다.그리고 귀하의 콜백을 실행하는 스레드 자체를 등록하지 않았습니다.

나는 C++ 콜백이 파이썬 콜백을 실행하지 않도록 설정했다. 대신 파이썬 프로그램이 읽는 소켓에 관련 데이터를 씁니다. 그런 다음 파이썬 프로그램은 소켓에서 관련 데이터를 가져올 때 콜백을 실행할 수 있습니다.