You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CPython API在C++线程中调用Python代码时线程异常终止问题

问题描述

我在C++项目中使用CPython API调用Python代码,原本单线程下的runPython函数(代码如下)以无限循环方式调用Python代码一切正常,无内存泄漏且可长期运行。

void runPython(){
    // init python module
    // load module
    // load function
    while(1){
        // create list using c-python api
        // populate input
        // call python function using c-python APIs
        // get output and free up the references
    }
}

但将该函数放入std::thread或pthread中执行时,Python代码执行到中途线程便异常终止,不再返回runPython函数,其他并行线程运行正常。尝试增大pthread栈至1000MB仍未解决问题。请问可能的原因是什么?(注:传入Python函数的是7-8个大小为100000的float32类型大列表)

可能的原因分析
  • GIL管理缺失:CPython的全局解释器锁(GIL)要求每个执行Python代码的线程必须先获取GIL。单线程下无需手动处理,但子线程中如果没有调用PyGILState_Ensure()获取锁,或操作完成后未用PyGILState_Release()释放锁,会直接导致Python运行时异常,引发线程终止。
  • 线程状态未初始化:CPython的API并非完全线程安全,每个线程调用Python接口前需要单独初始化线程状态。如果主线程未提前调用PyEval_InitThreads(),或子线程未通过PyThreadState_New()/PyThreadState_Swap()设置专属线程状态,会触发运行时错误。
  • 大对象操作的线程安全问题:虽然增大了线程栈,但Python列表对象在堆上分配,栈大小不影响。若子线程未持有GIL时创建或操作这些大列表,会触发内存访问冲突,导致线程崩溃。
  • Python异常未捕获:Python函数内部若抛出未捕获的异常,多线程环境下CPython API不会返回错误状态,而是直接终止当前线程。需要在调用Python函数后通过PyErr_Occurred()检查异常并处理,避免线程直接退出。
  • CPython版本兼容性bug:部分旧版本CPython在多线程调用API时存在线程状态管理的bug,建议切换到3.8及以上的稳定版本测试是否解决问题。

内容的提问来源于stack exchange,提问作者ABD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:55:33