在使用SWIG生成的Python扩展中,调用阻塞I/O代码后允许Python线程运行
我写了一个Python扩展,用来包装一个现有的C++库live555(具体来说是RTSP客户端接口),使用的是SWIG工具。这个扩展在单线程运行时可以正常工作,但一旦我调用库里的事件循环函数,Python解释器就再也无法控制了。所以,如果我在调用事件循环之前用threading.Timer
创建一个定时任务,一旦事件循环开始,这个任务就不会被执行了。为了解决这个问题,我手动在SWIG自动生成的包装文件中的每个doEventLoop()
函数调用前后加上了Py_BEGIN_ALLOW_THREADS
和Py_END_ALLOW_THREADS
这两个宏。但现在,我想在SWIG生成代码的时候就自动允许线程,而不想手动修改任何代码。有没有人做过类似的事情?
附注 - 我也考虑过换用其他框架(比如SIP)来解决这个问题。我选择SWIG而不是其他技术,是因为写SWIG接口真的很简单,我只需要包含现有的头文件。
1 个回答
5
SWIG提供了很多工具来帮助你实现这个目标。如果你只需要一个简单的解决方案,我过去常常在我的.swig文件里加上类似下面的内容:
%exception {
Py_BEGIN_ALLOW_THREADS
$action
Py_END_ALLOW_THREADS
}
这个方法利用了SWIG的功能,可以在C语言的函数调用中加入一些错误处理的逻辑,同时也能在调用时解锁和锁定GIL(全局解释器锁)。想了解更多细节,可以查看SWIG文档中的使用%exception进行异常处理。