【问题标题】:boost::python - how to invoke a python function in its own thread from C++?boost::python - 如何从 C++ 在自己的线程中调用 python 函数?
【发布时间】:2017-01-15 12:56:01
【问题描述】:

我有一个用 python 编写的模块。这个模块是我在 Python 中实现的许多不同功能的接口:

EmbeddingInterface.py 只是导入这个模块并创建一个实例:

import CPPController

cppControllerInstance = CPPController()

我想在 c++ 中使用 cppControllerInstance。这是我到目前为止所做的:

#include <Python.h>
#include <boost\python.hpp>

using namespace boost;

python::object createController()
{
    try
    {
        Py_Initialize();

        python::object mainModule = python::import("__main__");
        python::object mainNamespace = mainModule.attr("__dict__");

        python::dict locals;

        python::exec(
            "print \"loading python implementetion:\"\n"
            "import sys\n"
            "sys.path.insert(0, \"C:\\Projects\\Python\\ProjectName\\Panda\")\n"
            "import EmbeddingInterface\n"
            "controller = EmbeddingInterface.cppControllerInstance\n",
            mainNamespace, locals);

            python::object controller = locals["controller"];
            return controller;
    }
    catch(...) {}
}

问题:

这个“控制器”有一些必须异步调用的函数。 它的工作是连续的,此外它还可以抛出异常。 这就是为什么 std::async 听起来很棒的原因。

但它不起作用:

int main()
{
    python::object controller = createController();
    python::object loadScene = controller.attr("loadScene");
    //loadScene(); // works OK but blocking!
    std::async(loadScene); // non blocking but nothing happens!
    while(true); // do some stuff
}

我试图用自己的线程调用 python 函数“loadScene”,但该函数似乎被阻塞了。它永远不会回来。

这样做的正确方法是什么?

【问题讨论】:

    标签: python c++ multithreading c++11 boost-python


    【解决方案1】:

    看来你误解了std::async的行为

    测试代码的sn-p:

    #include <iostream>
    #include <chrono>
    #include <thread>
    #include <future>
    
    int doSomething(){
      std::cout << "do something"<<std::endl;
      return 1;
    }
    
    int main(){
       auto f = std::async(doSomething);
    
       std::this_thread::sleep_for(std::chrono::seconds(3));
       std::cout <<"wait a while"<<std::endl;
       f.get();
       return 0;
    }
    

    输出:

    wait a while
    do something
    

    换行

    auto f = std::async(doSomething);
    

    auto f = std::async(std::launch::async,doSomething);
    

    然后输出:

    do something
    wait a while
    

    作为您的示例,要立即在另一个线程中运行它,您可以尝试:

    std::async(std::launch::async,loadScene);
    

    【讨论】:

    • 确实,当时我不理解 std::async 的行为以及 std::future 析构函数阻塞的事实。但是关于在不同的 c++ 线程上调用 python 函数,它并不像你说明的那么简单,需要使用 GIL(python 全局解释器锁)进行操作。
    猜你喜欢
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    • 2013-12-05
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    相关资源
    最近更新 更多