Process A forks say 4 child processes. exec() is used to replace the code of the children. The children initialize and have to wait for the parent to create all of the 4 of them.
Then the parent sends a sigusr1 to each child process in order for them to start processing. The parent waits for all the children to complete procesing. When a child finishes its work it sends a sigusr2 to the parent. When the parent receives all the sigusr2 signals it continues with execution, merging the calculations of the child processes.
This is a university exercise, and it was stated in class that process A (parent) will lose some signals, so we were told to only require a percentage of the children signals to be received successfully.
I would like to achieve 100%. In the other case is a pause() and a loop going to work?
If you use the standard signal()
method, the process A can lose some signals if many children send him the same signal in a very short time. If you're handling a signal and receive during this time the same one, you will lose the second (more precisely it will be catched by the default signal handler).
If you decide to use sigaction()
you'll be able to catch all the signals sent to your process.
Other answerers have already covered how to avoid losing signals - that said, I would recommend not using signals at all. Since signals can break in at any point (even while locks are held!) it's very hard to write signal-safe code more complex than, say, writing a flag into a fifo or incrementing an eventfd.
As such, why not just use a pipe or eventfd to report completion? This not only guarantees that all messages written will make it to the parent process, but also avoids synchronization issues by allowing your process to receive data from the pipe/eventfd only when it's ready.
You must use sigaction()
; however again you can lose some of them because:
Signals are not queued. Child processes send SIGUSR2
and if they occur at the same time, only one of them will be delivered.
The best way is to use real time signals using sigqueue()
.
You will be use signal alrm and pause in parent process which wait till child process generate alarm signal which crack pause statement and sync them. .