Should I worry about the order in which the processes in the goup process receive signals?

I want to end a process group by sending SIGTERM to the processes inside it. This can be done using the kill command, but the manuals you found provide some details on how this works:

  int kill(pid_t pid, int sig); ... If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid. 

However, in what order will the signal be transmitted to the processes that form the group? Imagine the following situation: a pipe is installed between the main and subordinate processes in a group. If the slave is killed during kill(-pid) processing, and the master is still not there, the master may report this as an internal failure (after receiving a notification that the child is dead). However, I want all processes to understand that such termination was caused by something external to their process group.

How can I avoid this confusion? Should I do something more than just kill(-pid,SIGTERM) ? Or is it allowed by the basic properties of the OS, which I do not know about?

Please note that I cannot change the code of processes in a group!

+4
source share
4 answers

Try this as a three-step process:

 kill(-pid, SIGSTOP); kill(-pid, SIGTERM); kill(-pid, SIGCONT); 

The first SIGSTOP should put all processes in a stop state. They cannot catch this signal, so this should stop the whole group of processes.

SIGTERM will be queued for the process, but I do not believe that it will be delivered because the processes will be stopped (this is from memory, and I cannot find the link, but I believe that this is true).

SIGCONT will start the processes again, allowing the delivery of SIGTERM. If the slave first receives SIGCONT, the master can still be stopped, so he will not notice that the slave is leaving. When the master receives SIGCONT, SIGTERM will follow, completing it.

I don’t know if this will really work, and it may be an implementation, depending on when all the signals are actually delivered (including SIGCHLD to the main process), but it may be worth a try.

+5
source

I understand that you cannot rely on any particular signal delivery order.

You can avoid the problem if you send the TERM signal only to the master process, and then the master kills its children.

+1
source

Even if all of the various UNIX variants promise to deliver signals in a specific order, the scheduler may still decide to run the critical code of the child process to the parent code.

Even your STOP / TERM / CONT sequence will be vulnerable to this.

I'm afraid you might need something more complex. Perhaps a child process can catch SIGTERM and then loop until its parent exit exits before it exits? Be sure and add a timeout if you do.

+1
source

Unconfirmed: use shared memory and put some kind of β€œwe are dying” semaphore that can be checked before I / O errors are considered real errors. mmap () with MAP_ANONYMOUS | MAP_SHARED and make sure it survives your fork() process path.

Oh, and be sure to use the volatile keyword, or your semaphore is optimized.

0
source

Source: https://habr.com/ru/post/1315275/


All Articles