我如何暂停 child 进程并重置它

how i can suspend child process and reset it

我正在 shell 中创建一个带有 fork 的 child 进程,并分配这个 child 进程来执行命令,例如:"ls -lR /",使用 'execve()' 就像你在我的代码中看到的那样,当我收到 SIGTSTP 时,我想用 kill(child_process, SIGTSTP) 停止这个 child 进程,当你键入 "fg" 命令时,我必须重置这个 child 使用 kill(child_process, SIGCONT) 运行,问题是 wait(&status) 在我收到 SIGTSTP 之后 return 仍在等待 child 结束, -- 那么我该怎么做呢??

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int child_pid;
int parn_pid;

void    func1(int sig)
{
    kill(child_pid, SIGTSTP);
}

int main()
{
    int sig;
    int status;
    char *argv[] = {"ls", "-lR", "/", NULL};

    signal(SIGTSTP, func1);
    child_pid = fork();
    if (child_pid == 0)
    {
        child_pid = getpid();
        execve("/bin/ls", argv, NULL);
        exit (1);
    }
    else
    {
        parn_pid = getpid();
        waitpid(child_pid, &status, WUNTRACED);
        printf("\nsuspended\n");
        if (WIFSTOPPED(status))
        {
            sleep(2);
            kill(child_pid, SIGCONT);
            wait(&status);
        }
    }
    return (0);
}

您需要使用 waitpid() 而不是 wait()。使用 wait() 将等待 child 进程被 终止 ,这意味着进程必须已经退出,例如从 SIGKILL 或 SIGSEGV。您正在尝试等待进程停止,这不是一回事。停止一个进程只是暂停它,它允许它稍后继续。它不会退出。

您需要将 WUNTRACED 标志与 waitpid() 一起使用,以等待 child 个进程终止 或停止 。如waitpid(child_pid, &status, WUNTRACED)waitpid(-1, &status, WUNTRACED).

还有一个与此相关的缺陷。 WIFSIGNALLED()WTERMSIG() 也仅适用于由信号终止的处理。您应该改用 WIFSTOPPED()WSTOPSIG() 来检测 child 是否已停止。

另请注意:

  • SIGSTOP也可以停止一个进程。
  • 您可能会在设置信号处理程序后随时收到 SIGTSTP,这可能是在 child_pid 被赋值之前。
  • wait() 如果您的进程被信号中断,朋友们可以 return -1 将 errno 设置为 EINTR