Pybind11:为啥来自 Python 的异步调用不能在 C++ 中正确执行回调?

Posted

技术标签:

【中文标题】Pybind11:为啥来自 Python 的异步调用不能在 C++ 中正确执行回调?【英文标题】:Pybind11: Why doesn't asyn call from Python execute the callbacks properly in C++?Pybind11:为什么来自 Python 的异步调用不能在 C++ 中正确执行回调? 【发布时间】:2020-04-12 07:58:49 【问题描述】:

我有一个 Python 方法,它是这样实现的:

def start(self):
    try:
        self.is_running = True
        self._main_loop()

    except Exception as ex:
        path='exceptions-servicecore.log'
        track = traceback.format_exc()
        exception_time = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
        with open(path, 'a') as f:
            f.writelines(f'\nexception_time : exception occured ex.args \ntrack')

def start_async(self):
    st = threading.Thread(target=self.start) 
    st.start()

这里的_main_loop() 然后运行一堆命令并执行从 C++/C# 等发送的回调。使用Pybind11 我只需像这样调用start_async

this->startFuncAsync = this->obj.attr("start_async");
...
CORE_API void Core::Start(bool async)

    try
    
        if (async)
        
            this->startFuncAsync();
        
        else
        
            this->startFunc();
        
    
    catch (std::exception ex)
    
        std::cout << ex.what() << std::endl;
    

但看起来,它只是无法正常运行。

它在 Python 中运行良好,但是当涉及到调用上面的 C++ 函数的 C++ 或 C# 时,它不会显示任何输出!当我将它们的执行记录到文本文件时,调用回调的 Python 部分确实有效。但是客户端没有任何活动。我看不到任何用 C++ 或 C# 生成的输出。回调正在工作并在控制台(C++ 或 C#)上输出所需的信息。但是,非异步函数 (start) 可以正常工作。

所以我的问题是,这是预期的行为吗?无论在 Python 中或外部如何调用该函数,这是否都不起作用?

【问题讨论】:

【参考方案1】:

这个问题似乎与Pybind11有关。即只有一个执行线程可以工作,所有操作必须在同一个线程下执行。 如果该方法像我们在这里(开始)那样在python中作为单独的线程启动,在c ++中调用其他方法将使用不同的线程,因此您可以与之交互,它将变得像僵尸线程,因为您不会能够与之交互甚至停止它。 合乎逻辑的方法是在您可以控制线程的 C++ 端执行此操作。

【讨论】:

以上是关于Pybind11:为啥来自 Python 的异步调用不能在 C++ 中正确执行回调?的主要内容,如果未能解决你的问题,请参考以下文章

导入错误。pybind11和PCL加载DLL失败。

如何通过pybind11在python中捕获C++的异常?

pybind11 相当于 boost::python::extract?

pybind11 解释器使用捆绑的 python 可执行文件

pybind11:将 MPI 通信器从 Python 发送到 CPP

基于pybind11为C++提供Python接口