【问题标题】:Waiting for child process to terminate, or not - C等待子进程终止或不终止 - C
【发布时间】:2014-04-11 01:59:22
【问题描述】:

我正在尝试为我的一门课程做作业,但没有教授/同学回复我。所以在你回答之前,请不要给我任何确切的答案!只有解释!

我要做的是编写一个 c 程序 (timeout.c),它接受两个命令行参数,W 和 T,其中 W 是子进程在退出之前应该花费的时间量,以秒为单位,T 是在终止子进程并打印出“超时”消息之前,父进程应该等待子进程的时间。基本上,如果 W > T,应该有一个超时。否则,孩子应该完成它的工作,然后不会打印超时消息。

我想做的只是让父进程休眠 T 秒,然后杀死子进程并打印出超时,但是在这两种情况下都不会打印出超时消息。如何检查子进程是否已终止?有人告诉我为此使用 alarm(),但是我不知道该函数有什么用途。

这是我的代码,以防有人想看:

void handler (int sig) {
    return;
}

int main(int argc, char* argv[]){
    if (argc != 3) {
    printf ("Please enter values W and T, where W\n");
    printf ("is the number of seconds the child\n");
    printf ("should do work for, and T is the number\n");
    printf ("of seconds the parent process should wait.\n");
    printf ("-------------------------------------------\n");
    printf ("./executable <W> <T>\n");
    }

    pid_t pid;
    unsigned int work_seconds = (unsigned int) atoi(argv[1]);
    unsigned int wait_seconds = (unsigned int) atoi(argv[2]);

    if ((pid = fork()) == 0) {
        /* child code */
        sleep(work_seconds);
        printf("Child done.\n");
        exit(0);
    }

    sleep(wait_seconds);
    kill(pid, SIGKILL);
    printf("Time out.");

    exit(0);
}

【问题讨论】:

  • 通过wait/waipid可以得到子进程的状态

标签: c process fork child-process waitpid


【解决方案1】:

虽然 waitpid 会为您提供子进程的返回状态,但其默认用法会强制父进程等到子进程终止。

但是您的要求(如果我理解正确的话)只希望父母等待一段时间,可以使用 alarm() 来做到这一点。

然后,您应该使用带有特定选项的 waitpid(),如果孩子尚未退出,则该选项会立即返回(研究 api 的参数)。所以如果孩子没有退出,你可以杀死它,否则你已经收到它的返回状态。

【讨论】:

    【解决方案2】:

    您希望timeout 程序在命令完成后或多或少地停止,因此如果您说timeout -t 1000 sleep 1 保护程序在大约 1 秒后停止,而不是在 1000 秒后停止。

    做到这一点的方法是设置某种警报——通常是使用alarm() 系统调用和SIGALRM 的信号处理程序——然后让主进程执行wait() 或waitpid() 所以当孩子死后,它会醒来并收集尸体。如果父进程收到警报信号,它可以打印其消息并向其子进程发送某种死亡威胁。在求助于 SIGKILL 之前尝试 SIGTERM 和/或 SIGHUP 可能是明智的; SIGTERM 和 SIGHUP 信号给错误的孩子一个清理的机会,而 SIGKILL 则没有。

    【讨论】:

      【解决方案3】:

      如果您知道如何管理信号,则可以在父进程中捕获 SIGALRM 和 SIGCHLD。 SIGCHLD 将在客户端终止时引发,并在计时器到期时引发 SIGALRM。如果第一个引发的信号是SIGALRM,则超时,否则,如果父捕获的第一个信号是SIGCHLD,则子在超时到期之前已经停止。

      wait() 或 waitpid() 仍然需要收集终止的孩子。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-08
        • 2021-11-07
        • 1970-01-01
        • 2020-09-09
        • 1970-01-01
        • 2023-02-21
        • 2020-04-21
        • 1970-01-01
        相关资源
        最近更新 更多