У меня проблема с функцией совместно используемой библиотеки, вызываемой из Python.
Рассмотрим эту упрощенную программу на C, которая получает изображение с камеры:
#include <stdio.h>
#include <someproprietarylibraryheader.h>
int myfunction() {
CameraHandle handle;
printf("Running... \n");
if(!camera_init(&handle) { // initialize the camera handle
return -1;
}
if(!camera_precapture(handle)) { // prepare for capture
printf("ERROR precapture\n");
return -1;
}
else {
printf("precapture OK\n");
}
if(!camera_capture(handle)) { // start frame capture (returns immediately)
printf("ERROR capture\n");
return -1;
}
else {
printf("capture OK\n");
}
if(!camera_wait(handle)) { // wait for capture to be completed
printf("ERROR wait\n");
return -1;
}
else {
printf("wait OK\n");
}
if(!camera_close(handle)) { // close the camera
printf("ERROR close\n");
return -1;
}
printf("Done!!\n");
return 0;
}
Если я скомпилирую этот код вразделяемая библиотека и вызов myfunction()
из программы на C, ссылающейся на нее, все работает как положено .
Однако рассмотрим, что произойдет, если загрузить библиотеку и вызвать myfunction()
из Pythonкак это:
from ctypes import *
mylib = cdll.LoadLibrary("mylib.so")
mylib.myfunction()
В этом случае программа зависает на неопределенный срок в строке camera_capture()
в C-коде.Однако, что-то интересное происходит, посылая KeyboardInterrupt
с CTRL+C
: непосредственно перед обработкой этого исключения интерпретатором, программа может возобновить работу, и myfunction()
продолжается и завершается нормально.
Это похоже назависшая нить.Действительно, запустив вышеуказанный скрипт Python с gdb
, я обнаружил, что проприетарный API камеры действительно создает некоторые потоки.И, изучая обратную трассировку, программа застревает при вызове nanosleep()
где-то в проприетарном коде.По-видимому, функция nanosleep()
не прерывается должным образом, но только при запуске в Python.
Еще один намек на то, что это проблема потока / прерывания, заключается в том, что если я запускаю скрипт Python в gdb
,Я могу сделать CTRL+C
с последующим continue
на неопределенный срок в точке зависания программы.Однако, если я установлю точку останова с b
, а затем continue
, программа возобновит работу и завершится правильно.
Кто-нибудь знает, что может помешать этой простой программе работать гладко при вызове из Python,и почему потоки, созданные библиотекой C, не завершаются должным образом при запуске из Python?Большое спасибо.