【问题标题】:Child process still does not run after receiving signal子进程收到信号后仍然没有运行
【发布时间】:2016-03-30 13:33:21
【问题描述】:

代码是this question的答案之一。

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


void
sigusr1( int pidno )
{
  fprintf(stderr, "Caught\n");
}

int
main()
{
  pid_t pid;

  signal( SIGINT, sigusr1 );
  if( (pid = fork()) == 0 ){
    pause();
    fprintf(stderr, "Child\n");
  }
  else
  {
    fprintf(stderr, "Parent\n");
    kill( pid , SIGINT ); //parent sends signal to child
  }
  pause();
  return 0;
}

子等待一个信号,收到后继续执行。

运行它我得到了

Parent
Caught

孩子收到信号后好像没有跑。按 Ctrl+c:

Parent
Caught
^CCaught
Caught
Child

谁能解释一下这里发生了什么?

【问题讨论】:

    标签: c linux signals


    【解决方案1】:

    pause() 被调用信号已经被孩子接收和处理之后。不幸的是,pause() easily introduces this kind of race condition

    time you parent                   child
    ---- --- ------                   -----
      0      signal(SIGINT,handler)
      1      fork()                   (hello)
      2      print("Parent")          (waking up)
      3      kill(..., SIGINT)        <<SIGINT>>               # RACE kill v pause
      4                               handler: print("Caught")
      5      pause()                  pause()
      6   ^C <<SIGINT>>               <<SIGINT>>
      7      handler: print("Caught") handler: print("Caught")
      8      exit                     pause()
      9                               (still running)
    

    要检查到底发生了什么,请尝试在 printfs 中添加 %i、getpid(),也许还可以在子分支的 pause() 调用之前再添加一个 printf()。

    sigsuspend() 和显式信号屏蔽在这里可能是更好的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-29
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多