在使用 SWIG 生成的 python 扩展中调用阻塞 i/o 代码后允许来自 python 的线程

SS.*_*SS. 1 python swig rtsp-client

我已经编写了一个 python 扩展,它在 SWIG 中包装了一个现有的 C++ 库live555(包装了特定的 RTSP 客户端接口)。该扩展在单个线程中运行时有效,但是一旦我调用库的事件循环函数,python 解释器就永远无法收回控制权。因此,如果我threading.Timer在调用事件循环之前使用right创建计划任务,则一旦事件循环开始,该任务就永远不会执行。要解决这个问题,我补充Py_BEGIN_ALLOW_THREADSPy_END_ALLOW_THREADS在包装周围的每一个CXX文件生成的SWIG自动手动宏doEventLoop()函数调用。但是现在,我想在 SWIG 生成代码本身时做同样的事情(即允许线程),而不是手动更改任何代码。有人在 SWIG 中做过类似的事情吗?

PS - 我也会考虑切换到任何其他框架(如 SIP)以使其正常工作。我选择 SWIG 而不是其他任何技术是因为编写 SWIG 接口真的非常容易,我只需要包含现有的头文件。

Wil*_*son 5

SWIG 为您提供了大量钩子来帮助实现这一目标。如果粗略的解决方案足以满足您的需求,我过去做过的一件事就是在我的 .swig 文件中放入这样的内容:

%exception {
    Py_BEGIN_ALLOW_THREADS
    $action
    Py_END_ALLOW_THREADS
}
Run Code Online (Sandbox Code Playgroud)

这 (ab) 使用 SWIG 工具用某种错误处理逻辑装饰 C 函数调用,以便用 GIL 解锁/锁定装饰这些调用。有关此处发生的情况的详细信息,请参阅SWIG 文档中的%exception 异常处理