c - 我如何暂停子进程并重置它

标签 c fork wait execve

我正在 shell 中使用 fork 创建一个子进程,并分配该子进程来执行 cmd,例如:“ls -lR/”,使用“execve()”,就像您在我的代码中看到的那样,当我收到 SIGTSTP,我想用 kill(child_process, SIGTSTP) 停止这个子进程,当你输入“fg”命令时,我必须用 kill(child_process, SIGCONT) 重置这个子进程,问题是 wait(&status) 在我收到 SIGTSTP 后永远不会返回仍在等待子进程结束, ——那么我该怎么做呢??

#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() 将等待子进程终止,这意味着进程必须已退出,例如从 SIGKILL 或 SIGSEGV 退出。您正在尝试等待进程停止,这不是一回事。停止进程只是暂停它,并允许稍后继续。它不会退出。

您需要将 WUNTRACED 标志与 waitpid() 结合使用来等待子进程终止或停止。例如 waitpid(child_pid, &status, WUNTRACED)waitpid(-1, &status, WUNTRACED)

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

另请注意:

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

关于c - 我如何暂停子进程并重置它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59184584/

相关文章:

c - fork() 系统调用和 while 循环

c++ - 一个很好的、简单的、可移植的解决方案,用于在 C++ 中等待直到按下输入

JavaScript 小部件必须等待 AngularJS 变量值

json - Node.js 在发送 json 对象之前等待 redis client.get

c - 访问函数中的双指针结构

c - C语言中的gets()接受参数

c - 打印 strtok 标记时出现段错误

c - 为什么 GlutPostRedisplay 和 sleep 函数在此代码中不起作用?

c - Linux 上的最大子进程数

c - 无法让我的代理服务器向客户端发送http请求的信息 - Socket编程