记一次嵌入式Python+SWIG入门开发 (二)

记一次嵌入式Python+SWIG入门开发 (二)

1、Python 子解释器

   一般情况下我们程序中只使用一个全局的 Python 解释器就够用了,但是在某些情况下,比如我们想要隔离两个线程的环境,例如加载的模块表(sys.modules)和模块搜索路径(sys.path)等,就需要用到子解释器了。Python 子解释器顾名思义就是在全局解释器下,再创见出一个或多个解释器,解释器之间可相互切换调用,但都是运行在全局解释器中。具体细节可查看 Python/C API 官方文档

  • 创建子解释器
      我们可以通过函数 Py_NewInterPreter 创建出一个子解释器,但是在创建之前需要通过函数 PyGILState_Ensure 获取 GIL (Global Interpreter Lock,即全局解释器锁)。

    #include "Python.h"
    class PythonEnv
    {
    public:
        PythonEnv();
        ~PythonEnv();
    
    private:
        void test();
    
        PyThreadState *m_pState;
        PyThreadState *m_pThread;
    };
    
    PythonEnv::PythonEnv()
    {
        PyGILState_STATE state = PyGILState_Ensure(); # 当前线程保存 GIL,并能够调用任意 Python 代码
        PyThreadState *save = PyEval_SaveThread(); # 释放 GIL ,并将当前线程状态重置为 NULL, 返回先前的线程状态
        PyEval_RestoreThread(save); # 获取 GIL ,并将线程状态设置为 save
        PyThreadState *m_pState = Py_NewInterpreter(); # 创建子解释器
        PyThreadState *m_pThread =  PyThreadState_New(m_pState->interp); # 在子解释器中创建新的线程
        PyThreadState_Swap(save); # 将当前线程状态设置为 save
        save = PyEval_SaveThread(); # 释放 GIL ,并将当前线程状态重制为 NULL, 返回先前的线程状态
        PyEval_RestoreThread(save); # 获取 GIL ,并将线程状态设置为 save
        PyGILState_Release(state); # 释放以前获取的所有资源
    }
    
  • 在子解释器中调用 Python
      创建完子解释器后,我们就可以在子解释器中调用 Python 代码了。但是需要注意的是,由于子解释器是多线程的,所以需要获取 GIL 后才能调用,此处我们用函数 PyEval_AcquireThread 获取 GIL,不可使用 PyGILState_Ensureÿ

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值