waitpid, wnohang, wuntraced. How do I use these
Asked Answered
B

2

42

I am a bit confused. As I understand, waitpid with a pid of -1 means that I wait for all child's to finish but if I add an option to the waitpid of WNOHANG, that options says to exit immediately if none have finished...These seems extremely confusing.

Why would I tell the computer to wait for child processes to finish and then immediately afterwards tell it to exit immediately if none of the childs have finished?

Can someone explain this option and the WUNTRACED options? I don't know what it means to be traced.

Bizarre answered 3/11, 2015 at 21:1 Comment(3)
pid = -1 means to wait for any child, not all of them. And "wait" is a technical term, referring to wait(2).Paleozoic
@Paleozoic Ah, yes any and all are very different. Thanks for the correction. Say I have 3 children...how does the computer determine which to wait for? Or is it a first come type of thing where if one of the children finish then the computer has technically waited and moves on?Bizarre
@Bizarre If you pass a pid of -1, it doesn't wait for all children to finish, it waits for any child to finish. Once any child has finished, it is being reaped.Medlock
M
20

If you pass -1 and WNOHANG, waitpid() will check if any zombie-children exist. If yes, one of them is reaped and its exit status returned. If not, either 0 is returned (if unterminated children exist) or -1 is returned (if not) and ERRNO is set to ECHILD (No child processes). This is useful if you want to find out if any of your children recently died without having to wait for one of them to die. It's pretty useful in this regard.

The option WUNTRACED is documented as below, I have nothing to add to this description:

WUNTRACED The status of any child processes specified by pid that are stopped, and whose status has not yet been reported since they stopped, shall also be reported to the requesting process.

Read the waitpid page from POSIX for more details.

Medlock answered 3/11, 2015 at 21:6 Comment(0)
U
108

You usually use WNOHANG and WUNTRACED in different cases.

Case 1: Suppose you have a process which spawns off a bunch of children and needs to do other stuff while the children are running. These children sometimes exit or are killed, but the kernel will hold onto their exit status until some other process claims it via wait() or waitpid(). So, your parent process needs to call wait()/waitpid() on occasion to let the kernel rid itself of the remains of the child. But we don't want wait()/waitpid() to block, because, in this case, our process has other things that it needs to do. We just want to collect the status of a dead process if there are any. That's what WNOHANG is for. It prevents wait()/waitpid() from blocking so that your process can go on with other tasks. If a child died, its pid will be returned by wait()/waitpid() and your process can act on that. If nothing died, then the returned pid is 0.

Case 2: Suppose your parent process, instead, wants to do nothing while children are running. You don't want to just have it do some thumb-twidling for-loop, so you use a normal wait()/waitpid() without WNOHANG. Your process is taken out of the execution queue until one of the children dies. But what if one of your children is stopped via a SIGSTOP? Your child is no longer working on the task you have set it to, but the parent is still waiting. So, you've got a deadlock, in a sense, unless the child is continued by some means external to your parent and that child. WUNTRACED allows your parent to be returned from wait()/waitpid() if a child gets stopped as well as exiting or being killed. This way, your parent has a chance to send it a SIGCONT to continue it, kill it, assign its tasks to another child, whatever.

Unroof answered 18/1, 2016 at 0:46 Comment(3)
Legendary explain!Accusation
so by default wait() or waitpid() does not inform the parent process for a child being stopped by a signal? Because the documenttion says "suspends execution of the calling thread until one of its children terminates." . So it is not clear to me whether "terminates" could be because of a signalLasso
Ah, the terms aren't very clear... my fault. "Terminated" means that the process has finished (or crashed due to a fault or was killed by a SIGKILL) and there is an exit code available for the parent to examine. Where I used "stopped" above, I should really have said "suspended" or "paused" (but the signal to do this is a "SIGSTOP", which is why I got sloppy as said "stopped"). Suspended processes (like when you use Ctrl-z in a shell) can be resumed later. So, any time a process terminates (via exit(val), a SIGKILL, a segfault) should allow a wait() to continue.Unroof
M
20

If you pass -1 and WNOHANG, waitpid() will check if any zombie-children exist. If yes, one of them is reaped and its exit status returned. If not, either 0 is returned (if unterminated children exist) or -1 is returned (if not) and ERRNO is set to ECHILD (No child processes). This is useful if you want to find out if any of your children recently died without having to wait for one of them to die. It's pretty useful in this regard.

The option WUNTRACED is documented as below, I have nothing to add to this description:

WUNTRACED The status of any child processes specified by pid that are stopped, and whose status has not yet been reported since they stopped, shall also be reported to the requesting process.

Read the waitpid page from POSIX for more details.

Medlock answered 3/11, 2015 at 21:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.