简体   繁体   English

在程序继续时保持进程运行 C++

[英]Keep process running while program continues C++

I want to be able to call a function in a python script through C++.我希望能够通过 C++ 在 python 脚本中调用函数。 The function will print some text to stdout.该函数会将一些文本打印到标准输出。

However, the python script takes about 1 minute to load the global variables to memory, so I want to keep the process alive in interactive mode, where I would be able to simply call the function again without loading all the variables again.但是,python 脚本需要大约 1 分钟才能将全局变量加载到内存中,因此我希望在交互模式下保持进程处于活动状态,在这种模式下,我可以简单地再次调用该函数而无需再次加载所有变量。

I know that I can run system commands using system , but the command must terminate before I can use the output.我知道我可以使用system运行系统命令,但该命令必须终止才能使用输出。 I am also aware that I can use CPython and call PyRun_SimpleFileEx on the file, but this will have to reload all the variables again我也知道我可以使用 CPython 并在文件上调用PyRun_SimpleFileEx ,但这将不得不再次重新加载所有变量

I don't have any code to show since I don't know how to do this.我没有任何代码可显示,因为我不知道如何执行此操作。 Is there any way I can do this without rewriting the whole python script in C++?有什么方法可以做到这一点而无需在 C++ 中重写整个 python 脚本?

Every PyRun_* function runs in the __main__ module, so any functions or variables you define stick around for future executions.每个PyRun_*函数都在__main__模块中运行,因此您定义的任何函数或变量都会保留以供将来执行。

For example, say we want to run the do_it function from this file (helper.py) multiple times:例如,假设我们要do_it运行此文件 (helper.py) 中的do_it函数:

from datetime import datetime as dt
from time import sleep
print("First load")

def do_it():
    print("Helper function called on demand: %s" % dt.now())
    sleep(1)

do_it()

We can simply invoke PyRun_SimpleFile once, and then access the function again using PyRun_SimpleString("do_it()\\n");我们可以简单地调用一次PyRun_SimpleFile ,然后使用PyRun_SimpleString("do_it()\\n");再次访问该函数PyRun_SimpleString("do_it()\\n"); . .

#define PY_SSIZE_T_CLEAN
#include <Python.h>

int main(int argc, char *argv[])
{
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);  /* optional but recommended */
    Py_Initialize();
    FILE *fp = fopen("helper.py", "rb");
    PyRun_SimpleFile(fp, "helper.py");
    for (int i = 0; i < 10; i++) {
        PyRun_SimpleString("do_it()\n");
    }
    if (Py_FinalizeEx() < 0) {
        exit(120);
    }
    PyMem_RawFree(program);
    return 0;
}

Note that this makes use of the "Very High Level Embedding" and is thus limited to evaluating strings.请注意,这使用了“非常高级的嵌入”,因此仅限于评估字符串。 For more complex arguments you may want to use the "Pure embedding" instead to grab the PyFunctionObject from the module and invoke it.对于更复杂的参数,您可能希望使用“纯嵌入”来从模块中获取PyFunctionObject并调用它。

Finally, you may want to look at pybind11 , a C++11 bridge between Python and C++.最后,您可能想看看pybind11 ,它是 Python 和 C++ 之间的 C++11 桥梁。 This should make it very easy to grab Python the function and call it directly from C++.这应该可以很容易地获取 Python 函数并直接从 C++ 调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM