void main ( )
{ int x;
signal (SIGUSR1, f);
x= fork ( );
if (x == -1) exit (1);
if (x != 0)
{ kill (x, SIGUSR1) ;
sleep (2);
exit (0);
}
}
void f ( )
{
printf ("signal received");
exit (0);
}
I think that the program above asks the system to launch the f function ( which displays "signal received" ) when the SIGUSR1 signal is received by the parent process. but I'm not sure about that, please feel free to correct or to give more details. Thank for the help !
One problem is that the child process doesn't do anything, but will return immediately from the
main
function, maybe before the parent process can send the signal.You might want to call e.g.
pause
in the child.For the sake of the exercise, here is a corrected version of the original code which will compile and run.
This does exactly what the original question suggested the program should do. Try it out and see what happens if you don't believe me.
BTW: I'm not very experienced at C. There are a number of comments asserting that using
printf()
in the child process is unsafe. Why?? The child process is a duplicate of the parent including virtual address space. So why isprintf()
unsafe?There are some mistakes in your code:
Avoid calling
printf( )
function in signal handler.SIGNAL(7)
manual provides a list of authorized functions calling them is safe inside signal-handlers. Read:Use return type of main()
int
; read "What shouldmain()
return in C?"x
should bepid_t
. (Process Identification).Now lets suppose your program compile and run (not interrupted by any other signal while handler executing): I am just indenting your code and shifting
f()
function definition before main because function declaration is missing, also adding some comments that you should read:In
main()
function, you registersf()
function forSIGUSR1
signal and after that callsfork()
to create a new process. In runtime asfork()
function returns a child-process starts executing in parallel with parent process.As I can see your code, I think that you understands that child-process is copy of parent-process except values of variables can be different from the point
fork()
returns and hencex
is different in child and parent process. We can use the return value from fork to tell whether the program is running in the parent-process or in child. But note that it is not parent but actually the child-process that receives signalSIGUSR1
. Value of self process id is always0
for any process. You checks the return valuex = fork()
that is pid of newly created child-process, in child-process value ofx
is0
and in parentx != 0
. Hence signal is sent from parent process to child process.Your comments:
I have impression that you don't consider that both processes execute concurrently and "it can be happen that soon after
fork()
create a child-process, child-process start executing and immediately terminate before parent-process can send a signal to child (or child-process can receive the signal)". In that case, functionf()
will never get a chance to execute and printf in signal handler never prints.But the possibility of what I have described just above is very low because fork takes time to create a new process. And even if you execute the code again and again most of the times signal sent from the parent process will execute signal-handler.
What is correct way of writing this code?
Code is x.c: Correct way is set a flag that indicates that signal handler executed and then call printf function on the bases of flag value outside signal-handler as I have described in my answer: How to avoid using printf in a signal handler? And reason behind it explained by Jonathan Leffler in his answer.
Now compile it and execute:
Notice child-process prints because parent sends signal to child(but parent process doesn't prints as no signal catch in parent). So behavior of above code still similar as you was getting in your code. Below I have added one more example in which I am trying to demonstrate that 'concurrent execution of processes results different at different instance of execution'(read comments).
In above code, two signals are registered in both parent and child process. Parent process doesn't sleeps but busy in a while loop until a signal sets flag. Similarly child-process has a loop that breaks as flag becomes 1 in signal-handler. Now compile this code and run repeatedly. I frequently tried an got following output in my system.
Notice output, one case is: "till child process created parent sent signal and enter in while-loop and when child-process get chance to execute(depends on CPU scheduling) it send back a signal to parents and before parent process get chance to execute child receives signal and prints message". But it also happens sometimes that before child printf print; parent receives and print message (that is I marked using arrow).
In last example I am trying to show child-process executes in parallel with parent- process and output can be differs if you don't applies concurrency control mechanism.
Some good resource To learn signals (1) The GNU C Library: Signal Handling (2) CERT C Coding Standard 11. Signals (SIG).