【问题标题】:Continue output after parent child termination , i am unable to perform the operation父子终止后继续输出,我无法执行操作
【发布时间】:2021-12-20 12:12:31
【问题描述】:
    #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 个进程,一个父进程和一个子进程。 父级打印从 0 到 1000 的“i”值,然后退出。 同时子进程在创建后休眠 5 秒, 向父级发送 SIGUSR1 信号,然后退出。
父级应捕获该信号,在标准输出上打印“收到 SIGUSR1 信号, 睡 2 秒”,睡 2 秒,然后继续打印数字。 但是子进程终止后我无法继续该进程。

【问题讨论】:

  • 我不确定 printf() 和 sleep() 是否可重入。不要从 sig 处理程序中调用它们。改为设置一个变量并从打印循环中检查该变量。
  • 很多事情都在制造问题。你不在父亲里面等孩子,孩子里面pid的值是什么?顺便说一句 printf 不是信号安全的。

标签: c operating-system signals fork parent-child


【解决方案1】:

如果我增加usleep 时间,对我来说一切正常,没有它父进程在子进程发送信号之前终止。 问题在于kill 调用,else 语句仅在子进程中执行,因此这意味着pid 的值是0killpid 0 向整个组发送信号,在这种情况给父母和孩子,你应该把它改成

kill(getppid(), SIGUSR1);

【讨论】:

    【解决方案2】:

    除了@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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-21
      • 2021-07-15
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      相关资源
      最近更新 更多