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

Estimating progress of embedded python script in C++

本文关键字:脚本 Python 嵌入式 估计      更新时间:2023-10-16

简介

假设我有一个带有嵌入式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 Progress Bar插槽并更新其值。但是上面描述了什么?在控制台应用程序中,我可以直接从Python打印cont。但是,对于使用GUI的任何C ,它都不是解决方案。是否有任何方法可以从C 代码级别确定Script.py的执行方式是循环的循环?或者也许还有其他解决方案可以服务于进度栏?

您可以将信号从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脚本之前,必须将其设置一次。

总结评论部分的结论:可以通过对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),请在此处查看。

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将被打印到控制台。