signal acknowledgement - linux

how to kill a child process on sending an interrupt with key stroke and then sending a signal to parent that the child process has been killed?

The parent process generally receives a signal whenever a child dies regardless. This is the SIGCHLD signal.
This signal can be blocked by the parent process, but otherwise it's always delivered when a child exits for whatever reason. The parent can tell why the child exited by using one of the wait family (aka wait, wait3, wait4, or waitpid) to harvest the return code.

It may be a challenge to get the child process to have focus, so that it gets keyboard events.
You can always use the kill command to send a signal to a given process. Don't let the name kill mislead you, you can send any signal with kill, kill -SIGNUM pid, but SIGTERM is the default, which will usually cause a process to exit.
So if you wanted to send a SEGV signal to process 11 you'd do
kill -SEGV 11
You could set up the parent to catch a signal, re-send it to the child via a call to kill(2), and then wait for the child to exit using waitpid.
The parent's signal handler would like something like so:
int status;
kill(child_pid, SIG_TO_SEND);/*send to child*/
waitpid(child_pid, &status);/* wait for child to give up */
If you were serious about keeping the parent up and knew the signal was only for the child you'd probably set a variable in the parent, get out of the signal handler, and then do the work of sending and waiting for the child. In general it's good to get out of signal handlers as quickly as you can.

Related

python3 signal handling for daemon process when parent process kill

I know that as the parent process terminates, the daemon process also terminates.
But I need to do some finishing work, can I apply signal handling?
If possible, what type of signal should it map to?
Also, is the signal generated by the child process and the signal caused by the parent's termination distinguished?

what is the safe way to notify parent process in signal handler?

When my child process crash, it need a lot of time to do coredump (because I dump hugepages) and then the parent got SIGCHLD, but it is too late for me. So I use signal handler in child process to notify parent process and then do coredump, I just want to send the child pid to parent process. But I am not sure which mechanism is safe in this case. pipe or ipc message queue or unix socket?
You haven't provided enough details, but I assume in almost all the languages that allow you to explicitly spawn a new process there is a mechanism to get the child PID right when it gets created.
For example in C when you call fork() if the child process is created successfully it returns the child PID.
Yeah, I choose POSIX message queue finally, though it may be unsafe to call mq_send() in signal handler.

What would cause a SIGTERM to not propagate to child processes?

I have a process on Linux that starts up 20 child processes via fork. When I kill the parent process, it will often kill all of the child processes, but sometimes it doesn't kill all of them, and I'm left with some orphaned processes. This isn't a race condition on startup, this is after the processes have been active for several minutes.
What sort of things could cause SIGTERM to not propagate to some child processes properly?
There is no automatic propagation of signals (SIGTERM or otherwise) to children in the process tree.
Inasmuch as killing a parent process can be observed to cause some children to exit, this is due to ancillary effects -- such as SIGPIPEs being caused when the child attempts to read or write to a pipeline with the dead parent on the other side.
If you want to ensure that children are cleaned up when your process receives a SIGTERM, install a signal handler and do it yourself.
If you use process group id (pgid) when sending a signal, the signal would be propagated to parent process and all its children.
To know pgid, use ps a -o pgid,command.

System V msg_send interrupted by SIGKILL

I have a multi-process application that works like so...
There is a parent process. The parent process queries a database to find work, then forks children to process that work. The children communicate back to the parent via System V message queues to indicate they're done with their work. When the parent process picks up that message, it updates the database to indicate that the work is complete.
This works okay but I'm struggling with handling the parent process being killed.
What happens is the parent receives a SIGINT(from CTRL-C), and then sends SIGKILLs to each of the children. If a child is currently blocking on a Sys V message queue write when it receives that signal, the write is "interrupted" by the signal and the blocking canceled and the parent never learns that the child's work was done, and the database never gets updated.
That means that the next time I run the script, it will re-run any work that was blocking on the System V queue write.
I don't have a good idea for a solution for this yet. Ideally I would like to be able to force the queue write to remain blocking even when it receives that SIGKILL but I don't think such a thing is possible.
Well SIGKILL is, by definition, immediately fatal to the process which receives it and cannot be trapped or handled.
That is why you should only use it as a last resort, when the process does not respond to more polite requests to shut down. Your parent process should start off by sending something like SIGINT or SIGTERM to the children, and only reset to SIGKILL if they don't exit within a reasonable period of time.
Signals like SIGINT and SIGTERM may still cause the system call in the child to return, with EINTR, but you can handle that and retry the call and let it complete before exiting.

If I have a SIGCHLD handler installed, is a *blocking* wait on a specific pid still going to work?

I've got something that uses a bunch of async forks to do it's work (underneath a toolkit).
In a specific region of code, I'm forking, and then doing a blocking wait on the child process.
Is the SIGCHLD handler going to gobble the signal before the blocking wait will see it, leaving me potentially hung, or is the wait always going to get something back?
A SIGCHLD handler gets fired on the event, the edge, of a child process exiting. A blocking call to waitpid() will wait for the condition, the level, of that specific child process no longer existing.
When the process exits, a SIGCHLD will be delivered, and its handler will execute normally. If there was a waitpid() blocking on that process, it will then return as normal, regardless of the presence of a signal handler.

Resources