2

I am writing a program where multiple child processes can be created and the parent process continues to execute even while the child processes have not been terminated. However, once they are terminated, I want them to be printed before prompting the user to create more child processes.

From my understanding of(waitpid((pid_t)-1, NULL, WNOHANG), it should wait and check for all terminated child processes

  • return 0 should there be no terminated processes
  • return pid of terminated process
  • return -1 for error

does it return multiple return values for each terminated child process?

pid_t temp;
while(waitpid((pid_t)-1, NULL, WNOHANG)){
     temp = (waitpid((pid_t)-1, NULL, WNOHANG) 
     if(temp == -1)
          //error code
     else if(temp == 0)
          break;
     else{
         //fprintf pid of terminated child process

         //this statement never gets executed when I run the code 
     }
}

(Not looking for code; just want to know if I am understanding the concept properly :-/ Read through man for waitpid)

Thank you!

melpomene
  • 84,125
  • 8
  • 85
  • 148
shay13
  • 37
  • 1
  • 6
  • 1
    Why are you calling `waitpid` twice per iteration? And what do you mean by "return multiple return values"? – melpomene Oct 30 '17 at 22:08
  • Calling `waitpid(-1, ...)` doesn't wait for *all* child processes. It waits for *any one* child process. – bnaecker Oct 30 '17 at 22:11
  • Thanks for the response! https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/com.ibm.zos.v2r2.bpxbd00/rtwaip.htm Oh I see, based on this I thought that it waits to see how many child processes have ended since the last time a process was created. For example if three child processes were created and two were terminated, how would I know to keep track of the two that were terminated? If it waits for any one child process, how would I know to keep track of other terminated processes? – shay13 Oct 30 '17 at 22:17
  • You keep track of which one terminated by the return value of `waitpid()`, which is the PID of the process which exited/terminated/stopped. – bnaecker Oct 30 '17 at 22:18
  • Are you actually using z/OS? – melpomene Oct 30 '17 at 22:21
  • @bnaecker but if there were multiple processes terminated? Would I continue calling waitpid() until it returns 0? – shay13 Oct 30 '17 at 22:21
  • @melpomene I am using UNIX – shay13 Oct 30 '17 at 22:23
  • @shay13 Which one? – melpomene Oct 30 '17 at 22:23
  • Yes, if multiple children terminate between calls, you can call `waitpid()` multiple times to get the exit status of all of them. It will return `0` (given your `WNOHANG` parameter) when you've reaped all of the children which have exited since the last time you called it. – bnaecker Oct 30 '17 at 22:24
  • The basic structure of the loop should be: `int corpse; int status; while ((corpse = waitpid((pid_t)-1, &status, WNOHANG)) != -1) { ...process corpse... }`. You can only wait once for a given process under most circumstances. – Jonathan Leffler Oct 30 '17 at 23:23

1 Answers1

0

A much better practice is the use of SIGCHLD signal which is sent to parent process when one of its children dies. Thus, catching it in parent can let you make every decision you need, for example construct a list of currently died children by waiting the way you basically did (looping on waitpid in non blocking mode). Beware that each call to waitpid catches a dead process (don't call it exactly the way you did, there is a comment on this subject). Then just before printing the prompt you can print the content of this list and, at the same time cleaning that list. Be careful to temporarily block SIGCHLD delivery in the meantime to prevent auto-concurrent list management.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • Thank you for the suggestion! Yes, I realized it was unnecessary to call waitpid() in my while loop and after inside the loop. I took the suggestion in the comment `while ((temp = waitpid((pid_t)-1, NULL, WNOHANG)) > 0) { }` :) I will look more into `SIGCHLD` thank you! – shay13 Oct 31 '17 at 18:54