In Unix, when a child process in background terminates, it sends a SIGCHLD signal to the parent to inform it that it terminated.
Does the same happen even if the process was in foreground? If so, this means the parent will just ignore it.
Is this right? Or if it is in foreground, then no signal is sent at all?
background and foreground are job control concepts, and are part of the the shell. They are applied to processes and do not affect which process spawned (exec-ed) another process.
A child process is the result of a fork()-exec() call. The child gets a parent pid of the process that executed the fork() call. This is the context of the SIGCHLD signal, the parent pid receives the SIGCHLD signal. It does not matter whether the child process is "foreground" or "background", only the ppid matters on exit of the process.
There's no such thing as foreground child. The term background process is used to simply refer that we are mainly dealing with the parent process (which may create a child processes to do a part its job). When a child process exits SIGCHLD is always sent to parent process. However, the parent process usually ignores it. If parent wants to deal with exit of child Or to do some action only after the exit of child, then it can use the wait() system call to get the status of child process.
Related
So the following function should be called to kill the parent process. But it leaves the child processes alive. I know you can pass a argument to the sigkill in shell command to kill all the child process under this process group. But how to do this in C?
kill(parent, SIGKILL);
You can send a signal to a process group by kill(a_negative_number, a_signal), or killpg().
See kill(2) for detail. Basically, when you fork() or execve(), the child process will have the same PGID(process group id).
Another way is to install a signal handle for the parent process. When a signal is received at the parent, parent send signal to it's children and kill them. See signal(2)
If I spawn a process in my linux C program and there are 2 processes in total, a parent process and a child process. I want: if one of these 2 processes exits, the other process also exits.
How to achieve this?
are there any similar source codes?
Note: I don't want to block both processes, e.g, I don't want the parent process to be blocked by wait()
thanks!
In father process you can use the waitpid system call. It will block until the child exits.
In the child process you cannot use waitpid. One option would be that the father will inform the child by sending it a SIGTERM on exit. But this will only work if the father won't get killed using SIGKILL. I would suggest to periodically send a signal using kill with param 0 to the father process. If this fails, the process has terminated.
From the kill(2) man page:
if sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a process ID or process group ID.
If the child exits, the parent will be sent a SIGCHLD. If the parent is going to die, it should notify the child somehow, or at least send it a SIGTERM.
http://linux.die.net/man/2/waitpid
Wait for any child process, then exit when you return from waitpid.
If the parent process exits, then the child process becomes a zombie process.
If the child exits, the parent can be notified by the wait system call. You can exit the parent by reading the status of it.
what does kill exactly do?
I have a parent process which is creating 100 (as an example) child processes one after another. At the end of any child's job, I kill the child with kill(pid_of_child, SIGKILL) and I cannot see that in ps output. But if something goes wrong with the parent process and I exit from the parent process with exit(1) (at this point only 1 child is there - I can check tht in ps), at that point I see a lot of <defunct> processes whose ppid is pid of parent process.
How is that possible? did kill not kill the child processes entirely?
kill doesn't kill anything. It sends signals to the target process. SIGKILL is just a signal. Now, the standard action for SIGKILL -- the only action, actually, since SIGKILL can't be handled or ignored by a process -- is to exit, that's true.
The "<defunct>" process is a child that hasn't been reaped, meaning that the parent hasn't called wait() to retrieve the exit status of the child. Until the parent calls wait(), the defunct (or "zombie") process will hang around.
Whenever a process ends, no matter how it ends (kill or otherwise), it will stay in the kernel's process table until its parent process retrieves its exit status (with wait and friends). Leaving it in the process table avoids a number of nasty race conditions.
If your parent process has exited, the children should get reassigned to init, which periodically reaps its children.
Yes, SIGKILL terminates the process, but in any case (either normal exit or terminated), processes have an exit status, which needs to be kept around for potential readers - as such an entry in the process table may remain until this is done. See http://en.wikipedia.org/wiki/Zombie_process .
kill - does it kill the process right away?
I found my answer and I set up a signal handler for SIGCHLD and introduced wait in that handler. That way, whenever parent process kills a child process, this handler is called and it calls wait to reap the child. - motive is to clear process table entry.
I am still seeing some child processes going for a few seconds even without its parent process dying. - how is this possible?
I am seeing this via ps. Precisely ps -o user,pid,ppid,command -ax and greping for parent process, child process and defunct.
A process goes defunct (zombie) immediately upon exiting (from a signal, call to exit, return from main, whatever). It stays zombie until wait'd on by its parent.
So, all processes at least briefly become zombies upon exit.
If the parent process takes a bit (because it was doing other work, or just because the scheduler hasn't given it CPU time yet) before calling wait, then you'll see the zombie for a bit. If the parent never calls wait, then when it eventually exits, init (pid 1) will adopt its zombied children, and call wait on them.
A child process goes defunct (becomes a zombie) only when its parent process hasn't died and hasn't yet waited for it. If the original parent died, then the child's parent becomes process ID 1, and that process's main task is to wait for its (inherited) children to die and remove them from the process list, so that they are not zombies. (Note: an orphaned child, or a daemon, is automatically inherited by PID 1; it does not get assigned to grandparents or great-grandparents up the hierarchy of processes.)
Between the time that the child dies and the parent collects the exit information via wait() (or waitpid(), or waitid() or any of the other variants), it is a zombie in the process list, shown as defunct by ps.
But to answer your question's title:
Yes, a process can go defunct without its parent dying.
(And it can only go defunct if its parent has not died.)
I have a parent and a child process written in C language. Somewhere in the parent process HUP signal is sent to the child. I want my parent process to detect if the child is dead. But when I send SIGHUP, the child process becomes a zombie. How can I detect if the child is a zombie in the parent process? I try the code below, but it doesn't return me the desired result since the child process is still there but it is defunct.
kill(childPID, 0);
One more question; can I kill the zombie child without killing the parent?
Thanks.
from wikipedia:
On Unix and Unix-like computer operating systems, a zombie process or defunct process is a process that has completed execution but still has an entry in the process table. This entry is still needed to allow the process that started the (now zombie) process to read its exit status.
If the parent fetches the exit status by calling wait, waitpid or the like, the zombie should disappear.
You can detect whether a process is alive through the wait functions (man wait).