使用ctypes调用带超时的C函数

2 投票
1 回答
1221 浏览
提问于 2025-04-16 13:20

我在一个Python项目中使用ctypes,目的是调用一些C语言的函数,这些函数可能需要几个小时才能返回结果。我的问题是,我想在一定时间后终止这个函数,即使它还没有完成计算,也要从Python代码中把它杀掉。

我尝试过使用多线程,但这并不能停止C函数。以下是我的代码。

lib_iw = cdll.LoadLibrary("./iw.so")

iw_solve = lib_iw.solve_iw # the C function which can take some hours for responding
iw_solve.restype = c_void_p
iw_solve.argtypes = [c_void_p]

def iw_solve2() :
    iw_solve(None)

def iw_solve_wtimeout(time_out) : # the function which thow $iw_solve and kill the execution of $iw_solver after $time_out seconds (but it doesn't work)
    t_solve = threading.Thread(None,iw_solve2,None,(),None)
    t_solve.run()
    t = time.time()

    while(t_solve.is_alive() and ((time.time() - t) < 2)) :
        time.wait(0.3)

    if(t_solve.is_alive()) :
        t_solve._Thread__stop()
        print "iw_solve was killed"
    else :
        print "iw_solve has respond"

这个方法不行:当我调用iw_solve_wtimeout(10)时,函数在10秒后并没有停止。

我还尝试过使用闹钟,但同样无法停止C函数。以下是我的代码。

lib_iw = cdll.LoadLibrary("./iw.so")

iw_solve = lib_iw.solve_iw # the C function which can take some hours for responding
iw_solve.restype = c_void_p
iw_solve.argtypes = [c_void_p]

def iw_solve_withtimeout(time_out) : # the function which thow $iw_solve and kill the execution of $iw_solver after $time_out seconds (but it doesn't work)
    signal.signal(signal.SIGALRM, handler)
    signal.alarm(time_out)
    try :
        print "debut iw_solve"
        signal.alarm(time_out)
        iw_solve(None)
    except Exception, exc:
        print exc
        return None;

这个代码也不行:当我调用iw_solve_wtimeout(10)时,函数在10秒后依然没有停止。

你们有没有什么想法可以用ctypes来实现这个功能?

非常感谢你的帮助。

Marc

1 个回答

0

这样做行不通,因为Python代码无法直接控制C代码的运行。这个方法只能在纯Python代码中使用。

即使这样做能成功,这也是停止线程的错误方式。你应该把线程看作是一种合作的工作。如果你想让一个线程停止,你需要请求它停止,然后等它完成。用合作的方式而不是强制的方式,可以避免很多麻烦的问题。

你需要做的是修改你的C代码,让它能够接收取消的信号。C代码需要定期检查这个信号。你可以通过ctypes回调或者其他很多方法来实现这一点。

但从根本上来说,你需要在你的C代码中提供一个明确的取消机制。

撰写回答