首页 > 解决方案 > 从 Python 调用共享库函数挂起(可能的线程/中断问题)

问题描述

我对从 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 代码中的行。但是,通过发送KeyboardInterruptwith会发生一些有趣的事情CTRL+C:就在解释器处理此异常之前,程序能够恢复并myfunction()继续并正常终止。

这看起来像一个挂起的线程。事实上,通过运行上面的 Python 脚本gdb,我发现专有的相机 API 确实创建了一些线程。通过检查回溯,程序似乎被困在nanosleep()对专有代码中某处的调用中。显然,该nanosleep()函数没有被正确中断,但只有在 Python 中运行时才被中断。

另一个暗示这是一个线程/中断问题的事实是,如果我在 中运行 Python 脚本,gdb我可以在程序挂起的地方无限期地执行。但是,如果我用and放置断点,程序将继续并正确终止。CTRL+Ccontinuebcontinue

有没有人知道什么可能会阻止这个简单的程序在从 Python 调用时顺利运行,为什么 C 库创建的线程在从 Python 运行时不能正确终止?非常感谢。

标签: pythonmultithreadingshared-librariesdeadlockctypes

解决方案


推荐阅读