接收用户定义的信号时,进程不会取消暂停

时间:2016-12-09 17:32:00

标签: c unix signals fork pause

我试图让两个进程在C中合作。为此,我使用pause()和用户信号,正如我的理解,pause()导致程序进入睡眠状态直到收到信号。我这样做:

pid_t child = fork();
if(child < 0) {
    perror("Fork error");
    exit(1);
}
    else if (child > 0) { //parent process
    //do something here, then:
        printf("Parent pausing\n"); 
        pause();
        printf("parent received sigusr2\n");    
        //do something
        kill(child, SIGUSR2);
        printf("Sent signal to child\n");   
        sleep(1);
        fflush(NULL);
        pause();
        kill(child,SIGTERM);                
        waitpid(child, &status, 0);
    }
    else { //child process
       //do something, then
       printf("Child sending sigusr2\n");
       kill(getppid(), SIGUSR2);
       printf("Child pausing\n");
       pause();
       //do something
       kill(getppid(), SIGUSR2);

       fflush(NULL);
       printf(frompipe);
       pause();             
}

(这可能会在之后出现问题我所显示的具体问题,但尚未在编码中获得)。所以我目前的输出是:

Parent pausing
Child sending sigusr2
Child pausing
User-defined signal 2

它就在那里停止,好像父进程没有收到信号(因为它没有打印parent received sigusr2)。程序终止,但进程陷入后台。我究竟做错了什么?

1 个答案:

答案 0 :(得分:1)

@Eugene Sh。是正确的:你需要一个信号处理函数。 pause(2) man page

  

pause()仅在捕获到信号并返回信号捕获函数时返回。

要使用sigaction(2)执行此操作,请添加到您的程序中:

void sigusr2_handler(int) { /* do nothing*/ }

然后,在fork()来电之前,添加

struct sigaction sa;
sa.handler = sigusr2_handler;
sa.mask = 0;
sa.sa_flags = 0;
sigaction(SIGUSR2, sigusr2_handler);

使用sigaction表示此处理程序将一直存在,直到您将其禁用(与signal(2)不同)。在fork电话会议之前将其设置为适用于父母和孩子; the man page说:“通过fork(2)创建的子项会继承其父级信号处置的副本。”

使用此代码,您的pause()电话应该返回。如果您想在sigusr2_handler内打印消息或做其他事情,您当然可以这样做,但我读过的一般建议是让您的处理程序尽可能简单。

(顺便说一下,我还会在每个fflush之后添加printf次调用,以便在调试时保持安全。我认为这不应该是必要的,但它不会受到伤害! )