等待子进程终止或不终止 - C

时间:2014-04-11 01:59:22

标签: c process fork child-process waitpid

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

我要做的是编写一个ac程序(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);
}

3 个答案:

答案 0 :(得分:1)

虽然waitpid可以让你获得孩子的返回状态,但是它的默认用法会强制父等待孩子终止。

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

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

答案 1 :(得分:0)

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

这样做的方法是设置某种警报 - 经典地,使用alarm()系统调用和SIGALRM的信号处理程序 - 然后让主进程执行{{1} }或wait()以便当孩子死亡时,它会醒来并收集尸体。如果父进程获得警报信号,它可以打印其消息并向其子级发送某种死亡威胁。在诉诸SIGKILL之前尝试SIGTERM和/或SIGHUP可能是明智的; SIGTERM和SIGHUP信号为错误的孩子提供了清理的机会,而SIGKILL则没有。

答案 2 :(得分:0)

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

还需要wait()或waitpid()来收集被终止的孩子。