execv() 执行进程时,如何在 C 中杀死进程及其所有子进程?

How to kill a process and all of its children in C when executing the process by execv()?

我正在尝试在基于 unix 的操作系统上实现类似 timeout 的命令,如下所示:

int                  pid;
timer_t              timer_id;
struct sigevent      timer_event;
struct itimerspec    timer_value;

void timeout_signal_handler(int sig_no)
{
    kill(pid, SIGKILL);
}

int create_timer()                        { /* implementation */ }
int start_timer_oneshot(int interval_ms)  { /* implementation */ }

int main(int argc, char* argv[])
{

    int   status, pid_return;
    void  *signal_return;

    if (argc < 2)
        return EXIT_FAILURE;

    signal_return = signal(SIGUSR1, timeout_signal_handler);
    if (signal_return == SIG_ERR)
        return EXIT_FAILURE;

    create_timer();
    start_timer_oneshot(TIMEOUT);

    if ((pid = fork()) == 0)
    {
        execv(argv[1], &argv[1]);
        return EXIT_FAILURE;
    }
    else
    {
        status = -1;
        while (status == -1)
            status = wait(&pid_return);
    }

    return EXIT_SUCCESS;

}

我按如下方式使用此实用程序:

./timeout example

example 程序 运行 运行了几秒钟,并分叉了几个进程。当计时器在 timeout 到期时,只有 example 的父进程被终止,其子进程继续在控制台上打印。

当我 运行 没有 timeoutexample 并按下 Ctrl+C 时,父项及其所有子项都被成功杀死。

谁能告诉我如何在我的 timeout 程序中解决这个问题?

您想在 pid 0 上调用 kill()。这会将信号发送到调用进程的进程组的所有成员。

然而,这仅在已经 fork()/exec*() 的进程(或其子进程)不自行更改其(它们的)进程组的情况下才有效。

来自man 2 kill

If pid is 0, sig shall be sent to all processes (excluding an unspecified set of system processes) whose process group ID is equal to the process group ID of the sender, and for which the process has permission to send a signal.