在c+中使用python obj+;使用pybind和多处理

在c+中使用python obj+;使用pybind和多处理,python,c++,multiprocessing,pybind11,Python,C++,Multiprocessing,Pybind11,我尝试使用pybd11和AM来实现一个C++到python。不同之处在于,我想在C++中使用Python对象,并从C++中继续调用类方法。代码如下: #ifdef _WIN32 #include "direct.h" #define PATH_SEP '\\' #define GETCWD _getcwd #define CHDIR _chdir #else #include "unistd.h" #define PATH_SEP '/' #define GETCWD getcwd #defin

我尝试使用pybd11和AM来实现一个C++到python。不同之处在于,我想在C++中使用Python对象,并从C++中继续调用类方法。代码如下:

#ifdef _WIN32
#include "direct.h"
#define PATH_SEP '\\'
#define GETCWD _getcwd
#define CHDIR _chdir
#else
#include "unistd.h"
#define PATH_SEP '/'
#define GETCWD getcwd
#define CHDIR chdir
#endif
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <iostream>

namespace py = pybind11;
using namespace py::literals;
bool ChangeDirectory(const char* dir) { return CHDIR(dir) == 0; }
int wmain(int argc, wchar_t** argv)
{
    py::initialize_interpreter();
    PySys_SetArgv(argc, argv);

    std::string pyCode = std::string(R"(
import os
import sys
from queue import Empty, Full
from multiprocessing import Queue as mQueue, Process as mProcess
import sys
sys.executable = "C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe"
__file__ = "D:\\sw\\run.py"
print("Hello stackoverflow!", file=open("output.txt", "a"))
class C2PyMulti(object):
    """docstring for TactileEngine"""
    def __init__(self):
        self.te_ops = MultiProcessTest()

    def compose(self,data): 
        self.te_ops.load_q(data)

class MultiProcessTest(object):
    def __init__(self):
        self.my_q = mQueue()
        self.spawn_processes()

    def load_q(self, data):
        self.my_q.put(('print',data))

    def spawn_processes(self):
        args = (self.my_q,'inside message_coordinator')
        self.message_coordinator = mProcess(target=message_coordinator, args=args)
        try:
            # Starts the data processor
            val = self.message_coordinator.start()
            if val == 1:
                self.message_coordinator.join()
        except Exception:
            print('failed spawn!')


def message_coordinator(mQ,num):    
    print(num)
    while True:
        try:
            command, args= mQ.get(timeout=.0001)
            if  command == 'print':
                print(args, file=open("output.txt", "a"))  
            elif command == 'end':
                return 1
        except (Empty):
            pass


cpy2 = C2PyMulti()
cpy2.compose('hello')
cpy2.compose('hello')
cpy2.compose('hello')
cpy2.compose('hello')
cpy2.compose('end')
del cpy2
    )");
    try
    {
        FILE* f = nullptr;
        fopen_s(&f, "D:\\sw\\run.py", "wt");
        fprintf(f, "%s", pyCode.c_str());
        fclose(f);
        ChangeDirectory("D:\sw\run.py");
        //py::module C2py = py::module::import("run"); ///does not work can't find the module
        //py::object C2PyMulti = C2py.attr("C2PyMulti");
        //py::object c2py = C2PyMulti();
        //c2py.attr("load_q")("hello");
        py::exec(pyCode);
    }
    catch (const std::exception & e) {
        std::cout << e.what();
    }
    py::finalize_interpreter();
}
最后,我想使用类似于以下内容的内容:

py::module C2py = py::module::import("C2PyMulti");
py::object C2PyMulti = C2py.attr("C2PyMulti");
py::object c2py = C2PyMulti();
c2py.attr("load_q")("hello");

我的预约提前了。

所以要回答这个问题,我需要分离消息协调器方法,并通过另一个线程调用它,如:

void message(py::module C2py, py::object queue) {
    py::object message_coordinator = C2py.attr("message_coordinator")(queue, "In Message Coordinator!");
}
并通过
std::thread ti(message,C2py,q)调用它因此最终结果是:

#ifdef _WIN32
#include "direct.h"
#define PATH_SEP '\\'
#define GETCWD _getcwd
#define CHDIR _chdir
#else
#include "unistd.h"
#define PATH_SEP '/'
#define GETCWD getcwd
#define CHDIR chdir
#endif
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <iostream>
#include <thread>

namespace py = pybind11;
using namespace py::literals;
bool ChangeDirectory(const char* dir) { return CHDIR(dir) == 0; }

void message(py::module C2py, py::object queue) {
    py::object message_coordinator = C2py.attr("message_coordinator")(queue, "In Message Coordinator!");
}

int wmain(int argc, wchar_t** argv)
{
    py::initialize_interpreter();
    PySys_SetArgv(argc, argv);

    std::string pyCode = std::string(R"(
import os
import sys
from queue import Empty, Full
from multiprocessing import Queue as mQueue, Process as mProcess
import sys
sys.executable = "C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe"
__file__ = "D:\\sw\\run.py"
print("Start of module!")
class C2PyMulti(object):
    """docstring for TactileEngine"""
    def __init__(self):
        pass

    def build(self):
        return MultiProcessTest()

    def compose(self,te_ops, data): 
        te_ops.load_q(data)

class MultiProcessTest(object):
    def __init__(self):

        print("Start of MultiProcessTest!")
        #self.spawn_processes()

    def build_q(self):    
        self.my_q = mQueue()
        return self.my_q

    def load_q(self, data):
        self.my_q.put(('print',data))

    def spawn_processes(self):
        args = (self.my_q,'Inside message_coordinator')
        self.message_coordinator = mProcess(target=message_coordinator, args=args)
        try:
            # Starts the data processor
            self.message_coordinator.start()
        except Exception:
            print('failed spawn!')


def message_coordinator(mQ,num):    
    print(num)
    while True:
        try:
            command, args= mQ.get(timeout=.0001)
            if  command == 'print':
                print("command: {}, args: {}".format(command,args))  
            elif command == 'end':
                print("command: {}, args: {}".format(command,args))  
        except (Empty):
            pass

    )");
    try
    {
        FILE* f = nullptr;
        fopen_s(&f, "D:\\sw\\run.py", "wt");
        fprintf(f, "%s", pyCode.c_str());
        fclose(f);
        ChangeDirectory("D:/sw");
        py::module C2py = py::module::import("run");
        py::object C2PyMulti = C2py.attr("C2PyMulti");
        py::object c2py = C2PyMulti();
        py::object c2pybuild = c2py.attr("build");
        py::object b = c2pybuild();
        py::object q = b.attr("build_q")();
        py::object compose = c2py.attr("compose");
        compose(b, "fromoutside");
        compose(b, "fromoutside2");
        compose(b, "fromoutside3");
        compose(b, "fromoutside4");
        compose(b, "fromoutside5");
        compose(b, "fromoutside6");
        compose(b, "fromoutside7");
        compose(b, "fromoutside8");


        std::thread ti(message, C2py, q);
        compose(b, "fromoutside9");
        compose(b, "fromoutside10");
        b.attr("load_q")("hello4");
        b.attr("load_q")("hello5");
        b.attr("load_q")("hello6");

        while (true)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
        //py::exec(pyCode);
    }
    catch (const std::exception & e) {
        std::cout << e.what();
    }
    py::finalize_interpreter();
}
\ifdef\u WIN32
#包括“direct.h”
#定义路径\u SEP'\\'
#定义GETCWD\u GETCWD
#定义CHDIR\u CHDIR
#否则
#包括“unistd.h”
#定义路径_SEP'/'
#定义GETCWD GETCWD
#定义CHDIR CHDIR
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#包括
名称空间py=pybind11;
使用名称空间py::literals;
bool ChangeDirectory(const char*dir){return CHDIR(dir)==0;}
无效消息(py::模块C2py,py::对象队列){
对象消息协调器=C2py.attr(“消息协调器”)(队列,“在消息协调器中!”);
}
内部wmain(内部argc,wchar\u t**argv)
{
py::初始化_解释器();
PySys_SetArgv(argc,argv);
std::string pyCode=std::string(R)(
导入操作系统
导入系统
从队列导入空、满
从作为MQUE的多处理导入队列,将进程作为MPPROCESS
导入系统
sys.executable=“C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe”
__文件
打印(“模块开始!”)
类C2PyMulti(对象):
“”“TactileEngine的文档字符串”“”
定义初始化(自):
通过
def生成(自):
返回多进程测试()
def合成(自身、TEU操作、数据):
te_ops.load_q(数据)
类多进程测试(对象):
定义初始化(自):
打印(“开始多进程测试!”)
#self.spawn_进程()
def build_q(自我):
self.my_q=mQueue()
返回self.my_q
def加载_q(自身,数据):
self.my_q.put((‘打印’,数据))
def生成_进程(自身):
args=(self.my_q,“内部消息协调器”)
self.message\u coordinator=MPProcess(目标=message\u coordinator,args=args)
尝试:
#启动数据处理器
self.message\u coordinator.start()
除例外情况外:
打印('failed spawn!')
def消息协调器(mQ,num):
打印(个)
尽管如此:
尝试:
命令,args=mQ.get(超时=0.0001)
如果命令=='print':
打印(“命令:{},参数:{}”。格式(命令,参数))
elif命令=='end':
打印(“命令:{},参数:{}”。格式(命令,参数))
除(空):
通过
)");
尝试
{
FILE*f=nullptr;
fopen_s&f,“D:\\sw\\run.py”,“wt”);
fprintf(f,“%s”,pyCode.c_str());
fclose(f);
变更目录(“D:/sw”);
py::module C2py=py::module::import(“运行”);
py::对象C2PyMulti=C2py.attr(“C2PyMulti”);
py::object c2py=C2PyMulti();
py::object c2pybuild=c2py.attr(“build”);
py::object b=c2pybuild();
对象q=b.attr(“构建q”)();
py::object compose=c2py.attr(“compose”);
撰写(b,“来自外部”);
撰写(b,“来自外部2”);
撰写(b,“来自外部3”);
撰写(b,“来自外部4”);
撰写(b,“外部5”);
撰写(b,“来自外部6”);
撰写(b,“来自外部7”);
撰写(b,“来自外部8”);
std::线程ti(消息,C2py,q);
撰写(b,“来自外部9”);
撰写(b,“外部10”);
b、 属性(“负载”)(“hello4”);
b、 属性(“负载”)(“hello5”);
b、 属性(“负载”)(“hello6”);
while(true)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
//py::exec(pyCode);
}
捕获(const std::exception&e){

std::cout所以要回答这个问题,我需要分离消息协调器方法,并通过另一个线程调用它,如:

void message(py::module C2py, py::object queue) {
    py::object message_coordinator = C2py.attr("message_coordinator")(queue, "In Message Coordinator!");
}
并通过
std::thread ti(message,C2py,q);
调用它,因此最终结果是:

#ifdef _WIN32
#include "direct.h"
#define PATH_SEP '\\'
#define GETCWD _getcwd
#define CHDIR _chdir
#else
#include "unistd.h"
#define PATH_SEP '/'
#define GETCWD getcwd
#define CHDIR chdir
#endif
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <iostream>
#include <thread>

namespace py = pybind11;
using namespace py::literals;
bool ChangeDirectory(const char* dir) { return CHDIR(dir) == 0; }

void message(py::module C2py, py::object queue) {
    py::object message_coordinator = C2py.attr("message_coordinator")(queue, "In Message Coordinator!");
}

int wmain(int argc, wchar_t** argv)
{
    py::initialize_interpreter();
    PySys_SetArgv(argc, argv);

    std::string pyCode = std::string(R"(
import os
import sys
from queue import Empty, Full
from multiprocessing import Queue as mQueue, Process as mProcess
import sys
sys.executable = "C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe"
__file__ = "D:\\sw\\run.py"
print("Start of module!")
class C2PyMulti(object):
    """docstring for TactileEngine"""
    def __init__(self):
        pass

    def build(self):
        return MultiProcessTest()

    def compose(self,te_ops, data): 
        te_ops.load_q(data)

class MultiProcessTest(object):
    def __init__(self):

        print("Start of MultiProcessTest!")
        #self.spawn_processes()

    def build_q(self):    
        self.my_q = mQueue()
        return self.my_q

    def load_q(self, data):
        self.my_q.put(('print',data))

    def spawn_processes(self):
        args = (self.my_q,'Inside message_coordinator')
        self.message_coordinator = mProcess(target=message_coordinator, args=args)
        try:
            # Starts the data processor
            self.message_coordinator.start()
        except Exception:
            print('failed spawn!')


def message_coordinator(mQ,num):    
    print(num)
    while True:
        try:
            command, args= mQ.get(timeout=.0001)
            if  command == 'print':
                print("command: {}, args: {}".format(command,args))  
            elif command == 'end':
                print("command: {}, args: {}".format(command,args))  
        except (Empty):
            pass

    )");
    try
    {
        FILE* f = nullptr;
        fopen_s(&f, "D:\\sw\\run.py", "wt");
        fprintf(f, "%s", pyCode.c_str());
        fclose(f);
        ChangeDirectory("D:/sw");
        py::module C2py = py::module::import("run");
        py::object C2PyMulti = C2py.attr("C2PyMulti");
        py::object c2py = C2PyMulti();
        py::object c2pybuild = c2py.attr("build");
        py::object b = c2pybuild();
        py::object q = b.attr("build_q")();
        py::object compose = c2py.attr("compose");
        compose(b, "fromoutside");
        compose(b, "fromoutside2");
        compose(b, "fromoutside3");
        compose(b, "fromoutside4");
        compose(b, "fromoutside5");
        compose(b, "fromoutside6");
        compose(b, "fromoutside7");
        compose(b, "fromoutside8");


        std::thread ti(message, C2py, q);
        compose(b, "fromoutside9");
        compose(b, "fromoutside10");
        b.attr("load_q")("hello4");
        b.attr("load_q")("hello5");
        b.attr("load_q")("hello6");

        while (true)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
        //py::exec(pyCode);
    }
    catch (const std::exception & e) {
        std::cout << e.what();
    }
    py::finalize_interpreter();
}
\ifdef\u WIN32
#包括“direct.h”
#定义路径\u SEP'\\'
#定义GETCWD\u GETCWD
#定义CHDIR\u CHDIR
#否则
#包括“unistd.h”
#定义路径_SEP'/'
#定义GETCWD GETCWD
#定义CHDIR CHDIR
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#包括
名称空间py=pybind11;
使用名称空间py::literals;
bool ChangeDirectory(const char*dir){return CHDIR(dir)==0;}
无效消息(py::模块C2py,py::对象队列){
对象消息协调器=C2py.attr(“消息协调器”)(队列,“在消息协调器中!”);
}
内部wmain(内部argc,wchar\u t**argv)
{
py::初始化_解释器();
PySys_SetArgv(argc,argv);
std::string pyCode=std::string(R)(
导入操作系统
导入系统
从队列导入空、满
从作为MQUE的多处理导入队列,将进程作为MPPROCESS
导入系统
sys.executable=“C:\\Users\\nb\\scoop\\apps\\python\\current\\python.exe”
__文件
打印(“模块开始!”)
类C2PyMulti(对象):
“”“TactileEngine的文档字符串”“”
定义初始化(自):
通过
def生成(自):
返回多进程测试()
def合成(自身、TEU操作、数据):
te_ops.load_q(数据)
类多进程测试(对象):
定义初始化(自):
打印(“开始多进程测试!”)
#self.spawn_进程()
def build_q(自我):
self.my_q=mQueue()
返回self.my_q
def加载_q(自身,数据):
self.my_q.put((‘打印’,数据))
def生成_进程(自身):
args=(self.my_q,“内部消息协调器”)
self.message\u coordinator=MPProcess(目标=message\u coordinator,args=args)
尝试:
#启动数据处理器
self.message\u coordinator.start()
除例外情况外:
打印('failed spawn!')
def消息协调器(mQ,num):
打印(个)