Quote:
You'r right. 100% right. I should call exit(1) instead of continue. At that point, right after this exit, isn't the child process killed? If the child process is killed why would I need a way to handle zombies?
The process terminates, but isn't removed from the process table until you wait() for it. Things like runtime statistics and return value can still be gleaned from it until you do, which is why they keep it. You don't need to wait() for it at the bottom of your loop there(and thereby block until it quits) but
something in your program must do it sooner or later.
Fortunately it's not a big deal. There's nonblocking ways to check if a child has exited ( see
waitpid's WNOHANG flag ), ways to handle child exits asynchronously with sigaction and SIGCHLD(not reccomended; if you get two SIGCHLD's too fast to handle you might miss one), or you can just do a wait() loop in an independent thread. The thread method's probably the most bulletproof and least resource-intensive, the thread will spend 99.9% of its time asleep and only run when needed. (or when you want it to.)
I think you misunderstood a little with the exit(1). It doesn't have to be exit(1). In the example I showed I used execv(), which replaces the process with something else, so the exit(1) would only happen if execv() failed to load /bin/echo. If you're just doing your own thing you could have an exit(0) for normal return and exit(1) on error and so forth, it's just the return value for main().
---------- Post updated at 03:15 PM ---------- Previous update was at 02:58 PM ----------
It occurs to me to ask, how many loops does this program run? I figured it was like a daemon that takes several requests, which could create zombies forever which would be bad. If the loop only runs once and it quits thereafter, it's probably safe not to wait() if the child is disowned first. It will be owned by
init instead and waited for by it. Researching how to do this.