My Linux process has 4 children. After some execution time all children adopted by the init process. How do we prevent this situation? (this is not the case with Zombie processes).
The process is written in C and the OS is Linux. My code calls waitpid! What might be the problem? In 99,99% we don't have this problem.
Last update: What if someone executes "kill -9 "? This terminates immediately the parent process and leaves the children orphan.
If your processes are being reparented by init, that means that their parent process has died. When a process' parent dies, init adopts it so that it can reap the zombie by wait()ing on the child when it (that is, init) receives SIGCHLD.
If you do not want init to become the parent of your children, you will have to ensure that your process lives until all of your children have died and been reaped by your program.
Wait for the children to exit before exiting yourself. See the wait(2) man page for more details.
Check from main page for your waitpid API parameters, and make sure your parent process should not be over before all child processes are finished.
Can you post your code here?
Related
In C programming for Linux, I know the wait() function is used to wait for the child process to terminate, but are there some ways (or functions) for child processes to wait for parent process to terminate?
Linux has an extension (as in, non-POSIX functions) for this. Look up prctl ("process-related control").
With prctl, you can arrange for the child to get a signal when the parent dies. Look for the PR_SET_PDEATHSIG operation code used with prctl.
For instance, if you set it to the SIGKILL signal, it effectively gives us a way to have the children die when a parent dies. But of course, the signal can be something that the child can catch.
prctl can do all kinds of other things. It's like an ioctl whose target is the process itself: a "process ioctl".
Short answer: no.
A parent process can control the terminal or process group of its children, which is why we have the wait() and waitpid() functions. A child doesn't have that kind of control over its parent, so there's nothing built in for that.
If you really need a child to know when its parent exits, you can have the parent send a signal to the child in an atexit() handler, and have the child catch that signal.
In Linux, you can use prctl with the value PR_SET_PDEATHSIG to establish a signal that will be sent to your process when the thread that created it dies. Maybe you find it useful.
When a parent process ends, child process is adopted by init, so it is enough to check in child proces if ppid()==1 or ppid()!= than oryginal PPID
That means the parent process was finished.
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).