简体   繁体   中英

boost::python - how to invoke a python function in its own thread from C++?

I have a module written in python. this module is sort of an interface to many different functionalities I implemented in Python:

EmbeddingInterface.py simply imports this module and creates an instance:

import CPPController

cppControllerInstance = CPPController()

I would like to use cppControllerInstance in c++. this is what I have done so far:

#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(...) {}
}

The Problem:

This 'controller' has some functions which must be called asynchronously. its work is continuous and in addition it can throw exceptions. which is why std::async sounded great.

But it doesn't work:

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
}

I tried to invoke the python function 'loadScene' with its own thread but the function seemed to be blocking. It never returns.

What is the proper way of doing that?

Seems you misunderstood the behavior of std::async

a snippet of test code:

#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;
}

Output:

wait a while
do something

change the line

auto f = std::async(doSomething);

to

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

Then output:

do something
wait a while

As your example, to run it immediately in another thread, you can try :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM