2016-09-07 9 views
8

Mam moduł napisany w Pythona. Moduł ten jest swego rodzaju interfejs do wielu różnych funkcji I wdrożone w Pythonie:boost :: python - jak wywołać funkcję Pythona w swoim własnym wątku z C++?

EmbeddingInterface.py prostu importuje ten moduł i tworzy instancję:

import CPPController 

cppControllerInstance = CPPController() 

chciałbym używać cppControllerInstance w C++. to, co zrobiłem do tej pory:

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

problem:

Ten „kontroler” ma pewne funkcje, które mogą być wywoływane asynchronicznie. jego praca jest ciągła, a ponadto może powodować wyjątki. dlatego właśnie std :: async brzmiało świetnie.

Ale to nie działa:

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 
} 

Próbowałem wywołać funkcję Pythona loadScene 'z własnym wątku, ale wydawało się, że funkcja blokowania. Nigdy się nie zwraca.

Jaki jest właściwy sposób na zrobienie tego?

Odpowiedz

0

Wydaje Ci źle zachowanie std::async

fragment kodu testu:

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

wyjściowa:

wait a while 
do something 

zmienić linię

auto f = std::async(doSomething); 

do

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

Następnie wyjście:

do something 
wait a while 

W swoim przykładzie, żeby go od razu uruchomić w innym wątku, można spróbować:

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

Rzeczywiście, w tym czasie nie zrozumieć zachowanie std :: async i fakt bloków std :: future destructor. Ale jeśli chodzi o wywoływanie funkcji Pythona na innym wątku C++, nie jest to tak proste, jak to ilustrujesz i wymaga manipulowania przy pomocy GIL (blokada interpretera Pythona). –

Powiązane problemy