【问题标题】:How can I start a Python thread FROM C++?如何从 C++ 启动 Python 线程?
【发布时间】:2017-05-05 21:22:50
【问题描述】:

请注意,我只能使用 Python 2.6。我有一个 Python 2.6 应用程序,它使用使用 boost-python 构建的 C++ 多线程 API 库。我的用例只是从 C++ boost 线程执行 Python 函数回调,但尽管进行了许多不同的尝试并研究了所有可用的在线资源,但我没有找到任何可行的方法。所有提议的解决方案都围绕着不同的功能组合:Py_Initialize*PyEval_InitThreadsPyGILState_EnsurePyGILState_Release,但在尝试了所有可能的组合之后,实际上没有任何效果,例如

因此,这个问题是:如何从 C++ 启动和运行 Python 线程?我基本上想:创建它,使用 Python 目标函数对象运行它,然后忘记它。

这可能吗?

【问题讨论】:

  • 可以生成一个新进程吗?
  • 不,我必须在我所附加的解释器应用程序进程中创建一个线程。

标签: python c++ multithreading boost-python


【解决方案1】:

根据您的问题中的以下文字:

从 C++ 运行 Python 线程?我基本上想:创建它,使用 Python 目标函数对象运行它,然后忘记它。

您可能会发现使用sytem 简单地生成一个进程很有用:

system("python myscript.py")

如果你需要包含参数:

string args = "arg1 arg2 arg3 ... argn"
system("python myscript.py " + args)

【讨论】:

    【解决方案2】:

    您应该从您的 init 例程中调用 PyEval_InitThreads(并保留 GIL)。然后,您可以生成一个 pthread(使用 boost),并在该线程中调用 PyGILState_Ensure,然后调用您的 python 回调(PyObject_CallFunction?),释放任何返回值或处理任何错误(PyErr_Print?),使用PyGILState_Release 释放 GIL,然后让线程死掉。

    void *my_thread(void *arg)
    {
        PyGILState_STATE gstate;
        PyObject *result;
    
        gstate = PyGILState_Ensure();
    
        if ((result = PyObject_CallFunction(func, NULL))) {
            Py_DECREF(result);
        }
        else {
            PyErr_Print();
        }
    
        PyGILState_Release(gstate);
    
        return NULL;
    }
    

    【讨论】:

    • 谢谢,但这并不能回答这个 OP,这是我已经做过很多次的另一种可能的组合,并且以许多不同的方式但是好的,我将发布一个问题更新得到。您的答案对 Python-C++-concurrent-sup 有一些新的调料
    • 那么您还没有尝试过所有种可能的解决方案吗?
    • 好的,将PyObject_CallFunction的调用替换为boost“简化”层,但您仍然需要处理GIL。要么直接使用 C API,要么使用显示的 RAII 方法here
    • 看来 boost 会将 python 异常转换为 C++ 异常error_already_set,所以你绝对应该使用 RAII 方法来释放 GIL。除非您希望程序终止,否则您可能希望捕获异常...
    • 您还需要注意 boost python 对象析构函数调用 Py_DECREF 只能在持有 GIL 时完成。密切关注c++销毁RAII GIL wrapper和boost python函数对象返回的boost python object wrapper的顺序。
    【解决方案3】:

    对 OP How to call Python from a boost thread? 的回答也回答了这个 OP 或 DP (Derived:))。它清楚地演示了如何从 C++ 启动一个回调到 Python 的线程。 我已经对其进行了测试并且可以完美运行,尽管需要针对 C++11 之前的版本进行调整。它使用 Boost Python,确实是一个包罗万象的 5* 答案和example source code is here

    【讨论】:

      猜你喜欢
      • 2017-11-08
      • 1970-01-01
      • 2010-11-22
      • 2017-08-27
      • 1970-01-01
      • 2019-01-03
      • 2010-09-15
      相关资源
      最近更新 更多