如何将暂停的进程设置为后台? [英] How to set the paused process to background?

查看:98
本文介绍了如何将暂停的进程设置为后台?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C语言的新手.我正在尝试制作一个类似程序的shell.我当前正在制作一个信号处理程序,这意味着,当进程正在运行并且有人按下 ctrl + Z 时,该进程应该暂停并进入后台,而Shell必须继续.这里的问题是:父进程正在生成wait(NULL),但是子进程尚未结束程序,因此基本上父进程会等待尚未结束程序的子进程.如何使父级继续工作成为前台. (您可以看到我的代码如何将信号重定向到子级从父进程开始处理?在这里)

I am new in C. I am trying to make a shell - like program. I am currently making a signal handler, which means, when the process is running and somebody pressed ctrl + Z the process should pause and go to background while shell has to continue. The problem here is: parent process is making wait(NULL), but child is not ending the program so basically parent waits the child which is not ending the program yet. How to make it so that parent continues to work foreground. (you can see my code How to redirect signal to child process from parent process? here)

推荐答案

#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;
}

我认为以上代码可以达到您的目的.让我解释一下.

I think above code can serve your purpose. Let me explain it.

在您的代码中[如何将信号从父进程重定向到子进程?您已处理信号并从处理上下文发送相同的信号.当您按下Ctrl + cCtrl + z时,父子进程都会接收到信号.现在按照处理程序代码

In your code [How to redirect signal to child process from parent process? you have handled signal and from hander context sending same signal.When you pressed Ctrl + c or Ctrl + z both parent and child receives signal. Now as per the handler code

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

当处理程序将在父级上下文中执行时pid等于child's pid,因此它将发送信号给子级,但是当处理程序在子级上下文中运行时pid值将是0,因此它将信号发送给整个流程组,即父级和子级.这使您的代码可以无限次递归运行处理程序.因此,您收不到预期的结果.

when handler will execute in parent's context pid will be equal to child's pid so it will send signal to child but when handler runs in child context pid value will be 0, so it sends signal to whole process group i.e. parent as well as child. this make you code to run handler recursively for infinite times. Due to this you are not getting desired result.

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

I have modified two things to get desired result.

子上下文

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

In child context restore the signal action to the default upon entry to the signal handler so that when child receives signal for second time signal default action can be performed.

父上下文

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

use waitpid() instead of 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父进程将在子进程停止或终止时返回.

Due to WUNTRACED parent process will return when child will be stopped or terminated.

我希望它能为您服务,问我是否可以.

I hope it will serve you purpose ask me if it don't.

这篇关于如何将暂停的进程设置为后台?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆