估计C ++中嵌入式python脚本的进度

时间:2019-02-28 15:12:49

标签: python c++ progress-bar boost-python

简介

假设我有一个带有嵌入式python脚本的C ++应用。脚本会进行一些繁重的计算,这需要花费大量时间才能结束。完成后,我可以提取脚本的结果。但是,知道计算的实际停留时间将很方便-是现在完成10%还是完成一半的工作?这是一个示例代码(使用boot python):

app.cpp

#include <iostream>
#include <boost/python.hpp>

using namespace boost::python;

int main()
    try
    {
    Py_Initialize();
    object module = import("__main__");
    object name_space = module.attr("__dict__");
    exec_file("Script.py", name_space, name_space);

    object MyFunc = name_space["MyFunc"];
    object result = MyFunc();

    double sum = extract<double>(sum);}

Py_Finalize();

Script.py

def MyFunc():
    cont = 0
    while (cont < 10000):
        #...some calculations here, increasing "result" value on each step...
        cont +=1
    return result

问题

如果代码全部用C ++编写,我可以使用emit之类的本机框架工具来访问GUI进度条插槽并更新其值。但是在上述情况下呢?在控制台应用程序中,我每次都可以直接从python打印cont。但是,它不是任何带有GUI的C ++的解决方案。有什么方法可以从C ++代码级别确定在Script.py的哪个循环执行?也许还有其他解决方案可用于进度栏?

2 个答案:

答案 0 :(得分:1)

您可以将信号从python程序发送回C ++程序,例如:

if cont % 100 == 0:
    os.kill(cpp_progs_pid, signal.SIGUSR1)

然后在C ++中使用该信号的信号处理程序来使用emit

编辑:在您的C ++代码中,您需要传递程序的pid,如下所示:

#include <sys/types.h>
...
int pid = getpid(); // python's cpp_progs_pid
exec_file("Script.py", name_space, name_space, pid);

用类似这样的方式处理信号:

#include <signal.h>
...
void my_handler(int signum)
{
    if (signum == SIGUSR1)
    {
        // code to use emit
    }
}
...
signal(SIGUSR1, my_handler);  // set your signal handler

在C ++程序运行时,信号处理程序my_handler将被异步调用,因此您必须注意任何副作用。在调用python脚本之前,必须先设置一次。

答案 1 :(得分:0)

总结评论部分的结论: 通过给从python调用的函数提供回调可以解决该问题。 .cpp看起来像这样:

#include <iostream>
#include <boost/python.hpp>

using namespace boost::python;

int main(){
    Py_Initialize();
    object module = import("__main__");
    object name_space = module.attr("__dict__");
    exec_file("Script.py", name_space, name_space);

    object MyFunc = name_space["MyFunc"];
    object result = MyFunc();

    double sum = extract<double>(sum);}

    Py_Finalize();}

callback(int cont){
    int cont_final = 10000;
    double progr = cont / cont_final * 100;
    cout << cont << "\n";}

请记住,回调必须是静态成员或自由函数(在这种情况下,我已经显示了第二个选项)。如果您还需要传递状态(例如,由于GUI原因),请查看HERE

Python部分将是:

def MyFunc(callback):
    cont = 0
    while (cont < 10000):
        #...some calculations here, increasing "result" value on each step...
        cont +=1
        callback(cont) #Here we call progress update
    return result

就是这样-结果中从0到100的进度指示器将被打印到控制台。