从Python调用共享库函数挂起(可能是线程/中断问题)

2024-09-26 17:46:45 发布

您现在位置: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;
}

如果我将这段代码编译到一个共享库中,并从链接到它的C程序调用myfunction()一切都按预期工作。你知道吗

但是,考虑一下如果加载库并从Python调用myfunction(),会发生什么:

from ctypes import *

mylib = cdll.LoadLibrary("mylib.so")
mylib.myfunction()

在这种情况下,程序无限期地挂起在C代码的camera_capture()行。然而,通过用CTRL+C发送一个KeyboardInterrupt发生了一些有趣的事情:就在解释器处理这个异常之前,程序能够继续并且myfunction()继续并正常终止。你知道吗

这看起来像一根悬着的线。实际上,通过使用gdb运行上述Python脚本,我发现专有的cameraapi确实创建了一些线程。通过检查回溯,程序似乎被困在对nanosleep()专有代码中某个地方的调用上。显然,nanosleep()函数没有被正确中断,只是在Python中运行时才被中断。你知道吗

这是一个线程/中断问题的另一个提示是,如果我在gdb中运行Python脚本,我可以在程序挂起时无限期地执行CTRL+C,然后执行continue。但是,如果我用bcontinue放置一个断点,程序将恢复并正确终止。你知道吗

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


Tags: 代码程序closereturnifokerrorelse

热门问题