【问题标题】:Get returned value of a child process without holding parent execution在不持有父执行的情况下获取子进程的返回值
【发布时间】:2018-12-01 04:27:38
【问题描述】:

我需要能够从子进程获取返回值,而不必为它保留父进程的执行。

请注意子进程中可能发生运行时错误。

这是我正在尝试制作的程序:

//In parent process:
do
{
    read memory usage from /proc/ID/status
    if(max_child_memory_usage > memory_limit)
    {
        kill(proc, SIGKILL);
        puts("Memory limit exceeded");
        return -5; // MLE
    }
    getrusage(RUSAGE_SELF,&r_usage);
    check time and memory consumption
    if(memory limit exceeded || time limit exceeded)
    {
        kill(proc, SIGKILL);
        return fail;
    }
    /*
    need to catch the returned value from the child somehow with
    this loop working.
    Notice the a runtime error could happen in the child process.
    */
while(child is alive);

【问题讨论】:

  • 您可能希望wait()wait4() 带有WNOHANG 选项。

标签: c linux multithreading fork waitpid


【解决方案1】:

waitpid 函数有一个名为 WNOHANG 的选项,如果给定的孩子尚未返回,它会立即返回:

pid_t rval;
int status;
do {
    ...

    rval = waitpid(proc, &status, WNOHANG);
} while (rval == 0);

if (rval == proc) {
    if (WIFEXITED(status)) {
        printf("%d exited normal with status %d\n", WEXITSTATUS(status));
    } else {
        printf("%d exited abnormally\n");
    }
}

有关检查各种异常退出条件的更多详细信息,请参阅man page for waitpid

【讨论】:

    【解决方案2】:

    使用 WNOHANG 标志的解决方案仅在您只需要检查一次孩子的退出状态时才有效。但是,如果您想在孩子退出时获取退出状态,无论多晚,更好的解决方案是为 SIGCHLD 信号设置信号处理程序。 当子进程正常或异常终止时,会向父进程发送 SIGCHLD。在此信号处理程序中,您可以调用 wait 来获取子进程的退出状态。

    void child_exit_handler(int signo){
    
        int exit_status;
    
        int pid = wait(&exit_status);
    
        // Do things ...
    }
    // later in the code, before forking and creating the child
    signal(SIGCHLD, child_exit_handler);
    

    根据程序的其他语义,您可能希望改用waitpid。 (如果程序已停止而不是终止,也可能会调用 SIGCHLD。wait(2) 的手册页描述了用于检查这一点的宏。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-09
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      • 2015-08-06
      • 1970-01-01
      相关资源
      最近更新 更多