简体   繁体   中英

Child process still does not run after receiving signal

The code is one of the answers to 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;
}

The child waits for a signal, and after receiving it continues execution.

Running it I get

Parent
Caught

It seems that the child does not runs after receiving the signal. Pressing Ctrl+c:

Parent
Caught
^CCaught
Caught
Child

Can somebody explain me what is happening here?

pause() gets invoked after the signal has been received and handled by the child. Unfortunately, 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)

To check what exactly goes on, try adding %i, getpid() to printfs, and maybe also one more printf() before the pause() call in the child branch.

sigsuspend() and explicit signal masking might be a better choice here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM