使用 C++ 动态执行和终止外部程序

Dynamically executing and terminating external programs with C++

我需要在仍然控制每个进程的情况下执行进程。 我想创建一个 class 来存储线程或 pids 或任何必要的东西。

我目前有一个程序可以使用 C 函数 execvp 执行一个外部应用程序,还可以从 shell 脚本加载环境。所以我当前的程序正在阻塞。但是我需要能够自由地保留它 运行 并且只有在我终止当前 运行 或启动一个新的外部应用程序时才可以。

我目前的方法是创建一个使用 execve 函数的线程。但是据我所知,线程将被阻塞。

可能在线程中的代码(然后是变量):

char *argv[] = { "/bin/bash", "-c", "myApplication", 0 };
execve(argv[0], &argv[0], environment.data());

调用的应用程序可能未固定在代码中,它们的名称将由外部安装文件给出,包括参数。

现在我的实际问题是,是否有更好的方法来 "manage" 像 C++ 中那样的外部应用程序?一些现成的解决方案(class,库)?如果不是,如果这是实际的方式,我该如何终止线程。据说使用终止调用是不好的做法,这是我经常读到的。

我希望这对论坛来说已经足够具体了,因为我不知道如何再具体了。如果您需要更多提示,我想在这里创建什么,请随时在评论中提问。

更新:

致 DBus 和其他人:

附加信息我没有写我要启动的所有进程! 因此它将用于启动第 3 方应用程序,即使我有代码, 也不想更改。

您想 fork() 在执行之前。 fork() 是一个函数,它创建一个新进程 fork() 运行 的原始调用者相同 作为子进程。不同之处在于父进程将子进程的 pid 作为 return 值获取,而子进程获取 0。你想要做的事情的要点是:

pid_t pid = fork();

if( pid == 0 )
{
    // we're the child process
    char *argv[] = { "/bin/bash", "-c", "myApplication", 0 };
    int rc = execve(argv[0], &argv[0], environment.data());
    // execve only returns if there was an error
    // check 'errno' and handle it here
}
else if ( pid < 0 )
{
    // pid is less than zero, we didn't successfully fork,
    // there is no child process.
    throw "error message";
}

// do whatever processing the parent does

更多信息是 here. The kill() function isn't bad practice per se, if you want to quickly and gracefully end the subprocess you can write signal handlers in it, but you should be using something like dbus or zeromq 以进行正确的进程间通信。您想告诉程序做某事,而不仅仅是告诉它死掉(通常是您杀死它时想要它做的事情)。

永远不要在线程中使用 execv 函数 因为 execve() 系统调用用新的 process 图像覆盖了当前过程图像。

如果 fork-exec 或更好 vfork-exec 则为正确的模式。摘自联机帮助页:

vfork() 系统调用可用于创建新进程而无需完全 复制旧进程的地址 space,这在分页环境中效率极低。当 fork(2) 的目的时它很有用 本来是为 execve(2) 创建一个新的系统上下文。这 vfork() 系统调用与 fork(2) 的不同之处在于 child 借用了 parent 的内存和控制线程,直到调用 execve(2) 或 退出(通过调用 _exit(2) 或异常)。 parent 过程是 在 child 使用其资源时暂停。

使用 vfork 紧跟 execve,您避免了原始进程映像的副本,并且如果使用新进程则不会擦除,因此原始进程具有其 child和cat控制它,看它是否已经结束,给它发送信号等等。