我有一个从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;
}
如果我将此代码编译到共享库中,并从链接到它的C程序中调用myfunction()
,则一切正常。。
但是,请考虑一下,如果这样加载了libray并从Python调用myfunction()
会发生什么情况:
from ctypes import *
mylib = cdll.LoadLibrary("mylib.so")
mylib.myfunction()
在这种情况下,程序会无限期地挂在C代码中的行camera_capture()
上。但是,通过发送带有KeyboardInterrupt
的{{1}}会发生一些有趣的事情:在解释器处理此异常之前,程序可以继续运行,CTRL+C
可以继续正常终止。
这看起来像是挂线。实际上,通过使用myfunction()
运行上述Python脚本,我发现专有的相机API确实创建了一些线程。通过检查回溯,该程序似乎停留在专有代码内某个地方对gdb
的调用上。显然,nanosleep()
函数没有被正确中断,只有在Python中运行时才被中断。
另一个暗示这是线程/中断问题的事实是,如果我在nanosleep()
中运行Python脚本,则可以无限期地执行gdb
,然后执行CTRL+C
程序挂起。但是,如果我先用continue
然后再用b
设置断点,程序将继续执行并正确终止。
有人知道什么可能导致从Python调用此简单程序时无法顺利运行,为什么从Python运行时C库创建的线程不能正确终止?非常感谢。