首页 > 解决方案 > 父子终止后继续输出,无法执行操作

问题描述

    #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

static void sigusr(int iSig)   //SIGUSER are the user defined signals
  {
        if (iSig == SIGUSR1)
        {
                printf("Received SIGUSR1 signal, going to sleep for 2 seconds\n");
                sleep(2);
                
        }
  }
int main ()
  {
        int pid;
        signal(SIGUSR1, sigusr);
        pid = fork();
        if (pid > 0)   //Parent process created
        {
                for(int i=0; i<=1000;i++)
                {
                        printf("%d\n",i);
                    usleep(70);
                }
        }
        else           //Child process created
        {
                sleep(5);
                kill(pid,SIGUSR1);
                exit(0);
        }
   }

使用 fork() 创建 2 个进程,一个父进程和一个子进程。父级打印 'i' 从 0 到 1000 的值,然后退出。同时子进程在创建后休眠 5 秒,向父进程发送 SIGUSR1 信号,然后退出。
父级应该捕获该信号,在标准输出上打印“收到 SIGUSR1 信号,进入休眠 2 秒”,休眠 2 秒,然后继续打印数字。但是在子进程终止后我无法继续该进程。

标签: coperating-systemsignalsforkparent-child

解决方案


除了@complikator 的答案之外,您还应该在信号处理程序之外打印和睡眠。还有一些问题,例如“在收到信号之前完成主要完成”,但这实际上取决于您的用例......

看起来像这样:

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


volatile static bool called = false;

static void sigusr(int iSig)
{
    called = true;
}

void check_signaled(void) {
    if (called) {
        called = false;
        printf("Received SIGUSR1 signal, going to sleep for 2 seconds\n");
        sleep(2);
    }
}
int main(void)
{
    int pid;
    pid = fork();
    if (pid > 0)   //Parent process created
    {
        signal(SIGUSR1, sigusr);
        for(int i=0; i<=1000;i++)
        {
            check_signaled(); /* if signal come while iterating */
            printf("%d\n",i);
            usleep(70);
        }
        wait(NULL); /* wait child completion */
        check_signaled(); /* signal may happen "too late" */
    }
    else           //Child process created
    {
        sleep(1);
        kill(getppid(),SIGUSR1);
    }
}

推荐阅读