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.