c - 如何将暂停的进程设置为后台?

标签 c shell process signals fork

我是 C 的新手。我正在尝试制作一个类似于 shell 的程序。我目前正在制作一个信号处理程序,这意味着,当进程正在运行并且有人按下 ctrl + Z 时,进程应该暂停并转到后台,而 shell 必须继续。这里的问题是:父进程正在生成 wait(NULL),但子进程并未结束程序,因此基本上父进程等待尚未结束程序的子进程。如何使 parent 继续在前台工作。 (你可以在这里看到我的代码 How to redirect signal to child process from parent process?)

最佳答案

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

pid_t pid;

void send_signal(int signum){
        kill(pid, signum);
}

void init_signals(){
        signal(SIGINT, send_signal);
        signal(SIGTSTP, send_signal);
}

int main(){
        init_signals();
        pid = fork();
        if(pid > 0){
                //Parent Process
                printf("PARENT: %d\n", getpid());
                waitpid(pid, NULL, WUNTRACED);
                printf("Parent out of wait, i think this is what you are expecting\n");
        } else {
                struct sigaction act = {{0}};
                act.sa_handler = send_signal;
                act.sa_flags = SA_RESETHAND;
                sigaction(SIGTSTP, &act, NULL);
                sigaction(SIGINT, &act, NULL);
                perror("sigaction ");
                printf("CHILD: %d\n", getpid());
                // Child Process
                while(1){
                        usleep(300000);
                }
        }
        return 0;
}

我认为上面的代码可以达到你的目的。让我解释一下。

在您的代码中 [ How to redirect signal to child process from parent process?您已经处理了信号并且从处理程序上下文发送了相同的信号。当您按下 Ctrl + cCtrl + z 时, parent 和 child 都会收到信号。现在根据处理程序代码

void send_signal(int signum) {
     kill(pid, signum);
}

当处理程序将在父级上下文中执行时 pid 将等于 子级的 pid 因此它将向子级发送信号但是当处理程序在子级上下文中运行时 pid 值将为 0,因此它向整个进程组发送信号,即父进程和子进程。这使您编写代码以无限次递归地运行处理程序。因此,您没有得到想要的结果。

我修改了两件事以获得预期的结果。

child context

在子上下文中,在进入信号处理程序时将信号操作恢复为默认值,这样当子上下文第二次接收到信号时,可以执行信号默认操作。

parent context

使用 waitpid() 而不是 wait()。

pid_t waitpid(pid_t pid, int *status, int options);

The waitpid() system call suspends execution of the calling process until a child specified by pid argument has changed state.  By  default, waitpid() waits only for terminated children, but this behavior is modifiable via the options argument.

`WUNTRACED`   also  return  if  a child has stopped

由于 WUNTRACED,父进程将在子进程停止或终止时返回。

我希望它能为您服务,如果不能,请问我。

关于c - 如何将暂停的进程设置为后台?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49330644/

相关文章:

c - 奇怪的指针函数

c - Linux在运行时写入进程自己的可执行文件

c - C 中的二进制表示

regex - 如何使用 bash 将每一行提取到不同的变量中

c++ - 应用程序突然关闭时堆内存清理

Java 进程在启动外部进程后不会终止

c - SIGCHLD 处理 Beej 的指南示例

c++ - __in _out __in_opt _ allowed() 的目的是什么,它们是如何工作的?我应该在自己的代码中使用类似的结构吗?

linux - 解析参数的代码错误

python - 如何使用 python 进行 shell 导航