Is the kill function in Linux synchronous? Say, I programatically call the kill function to terminate a process, will it return only when the intended process is terminated, or it just sends the signal and return. If that is the case, how can I make it wait for the intended process to be killed?
No, since it doesn't kill anything, it only sends a signal to the process.
By default this signal can even be blocked or ignored.
You can't block kill -9 which represents sending SIGKILL
To wait for the process to die:
while kill -0 PID_OF_THE_PROCESS 2>/dev/null; do sleep 1; done
kill cannot be synchronous as it only sends a signal. The target process might ignore incoming signals (cf. SIG_IGN) so there's no guarantee regarding kill's effect.
It shouldn't be difficult to make an experiment verifying this hypothesis. Start process A and make it handle SIGTERM with a 10 second sleep before dying. Then start process B, which delivers a SIGTERM to A and exits immediately.
The kill system call does not wait for the other process to do anything. The signal is posted to the target process and the system call returns. The target process notices the signal when it is scheduled to run.
No. man 2 kill
man wait
See also man 7 signal for more details about Unix signals.
Related
I'm currently learning how signals really works in POSIX-systems. Signals such as SIGTERM can be caught and handled with custom handlers, this means that the kernel propagates the signal to the process itself. On the other hand SIGKILL is not catchable and cannot be handled firstly because it is its main purpose - kill the process. But I'm wondering does this means that the SIGKILL is not even propagated to the process ? I mean if the users will send kill -9 to some process using terminal the kernel will immediately purge that process without even forwarding the signal to it, or the signal will still be forwarded to the process but with the exception that we cannot add a custom handler to it? Sorry, if you consider this question dummy! I'm just starting with POSIX systems
some signals can catch and we name those catchable signals and some are uncatchable. The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
You can see a complete list of signals and appropriate action here.
I have some program, that I would like to run under supervision system. When program it to be stopped, it is sent SIGTERM signal, and, after some timeout, SIGKILL signal. My issue is that program exits ungracefully on SIGTERM -- it uses default handler.
Neither changing supervision system nor the program is option for me. I consider writing some kind of wrapper, that would fork the program, catch SIGTERM and request graceful exit in it, something in lines of this pseudo-C:
// wrapper.c
setsid();
signal(SIGTERM, &make_child_exit_gracefully);
pid = fork() ? waitpid(pid) : exec("/sbin/naughty-program");
Problem with that approach, that if naughty-program some-why reject request for graceful exit, SIGKILL from supervision system would kill wrapper, but program will just receive SIGHUP, which it can ignore. This way, I can end with wild naughty-program, re-parented to PID1 instead of being killed.
Is there more reliable solution? Is it possible to somehow inject non-trivial code to child process to be used as signal handler? Is it possible to map naughty-program into address space of wrapper and transmit control to it?
Ideally, I am looking for POSIX-compliant solution, although Linux-specific is fine too.
I have a C program running on Linux 3.12. This program spawns several child processes. One of these processes spawns a thread that runs for a bit then terminates. While this child process is running it performs an epoll_wait(). Periodically, the epoll_wait returns with an EINTR error. I setup the child process to catch the signal doing this interruption and found it is a signal 17, which, according to everything I have read is a SIGCHLD. Thing is, the thread this child process spawned is still running. It did not terminate. I also thought that threads do not generate a SIGCHLD on termination.
Any thoughts on why my process may be getting a signal 17?
The answer is a call to system(). This function in the code spawns a process to execute the shell command being passed in. The thread was calling system() to run some shell commands. When they finished the processes that was spawned ended and generated the SIGCHLD.
Do waitid/waitpid consume any pending SIGCHLD?
E.g., if one thread calls waitid while another one calls sigwaitinfo or reads from signalfd, can I assume that both calls return correct data when the child process terminates?
Found https://lkml.org/lkml/2009/1/10/181 :
That notification only tells us that at least one process has died;
SIGCHLD may only be pending once at a time. If further children die
before we clear the signal, nothing will happen.
...
Because it only tells us that at least one process has died, we have
to call waitpid() repeatedly until we have exhausted the wait queue.
~~Calling waitpid() does not clear the pending signal.~~
Мanpages do not mention "wait queue", but it explains a few things.
I wouldn't do that. The problem is that you do not know in which thread a signal is delivered (first). On the other hand sigwaitinfo() removes the signal from the pending signals set. So the thread calling waitpid() may never return.
Who in the kernel is responsible for killing a process.
What if a "kill" comes, and the process is in the blocked state. Does the kill waits until the process comes to running state to clean himself.
If someone can answer more in terms of kernel, like when a SIGINT from the kill command is generated, what all is invoked by the kernel until the TCBs (task control blocks) are cleared in the end.
I presume you are talking about SIGKILL, so I will confine the discussion to that signal only.
When a process raises a SIGKILL on another process, SIGKILL is added as a pending signal on the victim process, and any pending SIGSTOP, SIGTSTP, SIGTTOU or SIGTTIN signals are cleared. The victim is woken up (made runnable) if it is stopped or in an interruptible sleep state.
When the victim process next attempts to go from Kernel mode to User mode, the pending signals are checked. This is where the pending SIGKILL is found, and the Kernel calls do_exit() instead of going back to User mode.
The transition from Kernel mode to User mode will be when the process is next scheduled (unless it was in an uninterruptible sleep - this is the infamous D state). If it's in an uninterrutible sleep, the process won't try to go back to User mode until its woken.
Killing it with a signal other than SIGKILL, just causes a signal to be sent. This can be masked or ignored, but assuming it isn't (or after it's unmasked), then it interrupts the normal running of the program.
If an IPC-type system call is in progress (e.g. reading from a socket, select(), poll(), sleep() etc), then it will be interrupted and fail with EINTR in errno. A properly written application will re-issue the call after handling the signal.
The process then immediately executes a call to the signal handler, which may return to allow processing to continue, or it could call longjmp (in C), or it could exit the process, which is normally the default.
SIGKILL is completely different, none of the above happens. Instead it just quits the system call (which would presumably leave EINTR in errno, if the process was allowed to read it), then causes the task to exit immediately with no possibility to handle it.
But either of them I think waits for a "D" "uninterruptable sleep" state to finish. This would normally be something like a blocking disc read, page fault demand-load or something.
Running kill simply sends a signal to the process (TERM) asking it nicely to terminate. If it won't respond that's it's business. However, you can choose to send any one of several different signals commanding it to go away. What you may be interested in is kill -9 (SIGKILL) which kills it without giving it a choice in the matter.
(Edit: As was pointed out in the comments, TERM is the default)
Killing (rather than interrupting) is usually performed by the SIGKILL signal in UNIX systems (CTRL-C sends SIGINT).
These systems usually provide a method of interrupting blocking system calls by a signal, which allows the signal handler to execute without waiting on a system call to complete (This is where the EINTR error comes into play). So normally, the call is just cancelled, without waiting for it to complete.
Each process can recieve many types of signal, which it can ignore to handle but few aren't delivered to process but "Proceess scheduler" terminates the process....
see this for more explanation
http://www.linux-tutorial.info/modules.php?name=MContent&pageid=289