代码之家  ›  专栏  ›  技术社区  ›  TheWaterProgrammer

即使父进程已退出,系统仍将执行std::system吗?

  •  2
  • TheWaterProgrammer  · 技术社区  · 5 年前

    我正在跑步 C++ 控制台应用程序 嵌入式操作系统 环境。我想跑步 std::system 命令就是这样。我已采取 tar 举个例子。

    int main(int argc, char *argv[]) {
        std::system("tar xvzf /path/to/some/file.tar.gz");
        exit 0;
    }
    

    问题:
    如果我在 焦油 像上面这样的命令,tar命令会继续执行吗?
    我知道这有点取决于 焦油 是自己实现的。但是让我们说 焦油 父进程退出后不工作( 考虑最坏情况 )是否可以运行命令 STD::系统 在后台安全地命令并退出我的应用程序,是否相信它将在我的应用程序或父进程退出后完成其作业?

    2 回复  |  直到 5 年前
        1
  •  4
  •   Ted Lyngmo    5 年前

    由执行的命令 system() 以后通常不会继续 系统() 返回。 系统() 启动新进程(使用 fork() + exec*() CreateProcess() 等),然后等待该过程完成后再返回。但是,如果命令生成了孤儿,那么他们可以继续生活。

    这可能会有影响,取决于 SHELL 被使用 系统() :

    std::system("nohup tar xvzf /path/to/some/file.tar.gz &");
    

    自从 系统() 使用shell启动命令(可能 /bin/sh )它反过来使用流程的当前环境(最显著的是 PATH 以及可能用来影响命令所使用的共享库的变量——也可以通过重定向发送命令字符串,将命令置于后台(如上图所示)等——这通常被视为安全风险。最小化风险的一种方法是创建自己的系统函数,而不使用shell或环境。例子:

    #include <iostream>
    #include <array>
    #include <type_traits> // std::common_type_t
    #include <cstdlib>     // std::exit
    #include <utility>     // std::forward
    
    // fork, exec, waitpid
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <unistd.h>
    
    template<typename... Ts>
    int mysystem(Ts&&... ts) {
        int wstatus=-1;
    
        pid_t pid = fork();
    
        if(pid==0) {          // in child process
            std::array<std::common_type_t<Ts...>, sizeof...(ts) + 1> cmd{ std::forward<Ts>(ts)... };
            execv(cmd[0], const_cast<char* const*>( cmd.data() ));
            std::exit(1); // we'll only get here if execv failed starting the command
    
        } else if(pid!=-1) { // in parent process
            // wait for the child to terminate
            // the exit status from the child will be returned in wstatus
            waitpid(pid, &wstatus, 0); // 0 = wait forever
    
        } // else { /* fork() failed */ }
    
        return wstatus;
    }
    
    int main() {
        //int ws = mysystem("/usr/bin/find", ".");
        //int ws = mysystem("/usr/bin/bash", "-i");
        int ws = mysystem("/usr/bin/tar", "xvzf", "/path/to/some/file.tar.gz");
        std::cout << "--------------------\n"
                     "Exit status:        " << WEXITSTATUS(ws) << "\n"
                     "Termination signal: " << WTERMSIG(ws) << "\n"
                     "Core dumped:        " << std::boolalpha << WCOREDUMP(ws) << "\n";
    }
    
        2
  •  3
  •   darune    5 年前

    std::system 是一个阻塞呼叫… 这意味着在tar命令本身完成之前,您不会到达出口。