c++ - SWIG C++ Python 多态和多线程

标签 c++ python multithreading swig gil

我正在使用 SWIG 将第三方 C++ 包集成到 Python 应用程序中.该软件包通过网络连接到专有 API 并接收更新。总体流程是 python 实例化一个 C++ 对象,调用它的函数来设置它,然后等待更新。

我使用 SWIG's directors feature 实现了更新回调机制,并且在从 python 或 python 调用的 C++ 函数进行测试时,它运行良好。也就是说,我能够在 Python 中继承一个 C++ 类,从 C++ 调用它的虚函数,然后看到 python 代码优先执行。

问题:
当我收到来自网络的更新时,我得到:

The thread 'Win32 Thread' (0x1f78) has exited with code 0 (0x0).
Unhandled exception at 0x1e0650cb in python.exe: 0xC0000005: Access violation writing location 0x0000000c.

此异常是在 python27.dll 调用回调函数时抛出的。
我的怀疑是: 我违反了 GIL
AFAIU 更新来自不同的线程并使用该线程调用 python 的代码。

此时我不知所措。 SWIG 的导向器功能是否仅限于在 python 中启动的流(即来自 python 管理的线程)?
我该如何规避这个?我如何诱导从 C++ 到 python 的更新?甚至可以使用 SWIG 吗?
我应该使用完全不同的方法吗?

我愿意就此事提出任何建议...

最佳答案

如果您的 SWIG 包装的 C++ 代码在线程中调用回调例程,那么可能没有 GIL 问题 - SWIG 生成的代码不执行任何我见过的 GIL 管理,这意味着当 Python 代码调用在您的 C++ 代码中,您在整个调用过程中保留了 GIL。

但是,如果您的 C++ 代码将回调延迟到另一个线程,那么您很可能违反了 GIL。这很容易变通:在调用回调之前,调用 PyGILState_Ensure(),当回调完成时,调用 PyGILState_Release。引用http://docs.python.org/c-api/init.html ,“非 Python 创建的线程”部分。 (如果您在这里使用 C++ 异常处理,您可能需要格外小心以确保您可以发布 GIL。)

如果您还没有查看堆栈跟踪,那么有必要验证 NULL 指针取消引用在您的代码中不是愚蠢的事情。 (您可以附加到使用 VS/GDB/WinDBG 运行您的代码的 Python 进程;Python 执行将保持神秘,但您可以通过这种方式跟踪您的 C++ 代码。)

关于c++ - SWIG C++ Python 多态和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9569372/

相关文章:

c++ - C++链表覆盖先前的数据

c++ - 如何编写一个函数来替换#ifdef 和#endif 对?

python matplotlib 热图颜色条从透明

c++ - load-acquire 应该立即看到 store-release 吗?

android - 在Android中还有什么被认为是繁重的任务?

ios - 使用 NSOperation 和 NSOperationQueue 的好习惯是什么?

c++ - 如何以跨平台的方式在 C/C++ 中测试计算机的真实一般性能?

c++ - 使用 `std::string::c_str()` 将 `mkdtemp()` 的结果传递给 `const_cast<char*>()`

Python正则表达式匹配列表中的多个单词

python - 如何在新样式类中拦截对 python "magic"方法的调用?