Linux fork () and wait ()

I have one, bad smell problem :(

I have this code:

  int main(){

  pid_t child, parent;
  int status=0;
  int i;

  printf("parent = %d\n", getpid());

  for(i=1;i<=5;i++){
      if( (child = fork()) == 0){
          sleep(i);
          printf("i=%d, %d\n",i, getpid());
      }
  }
  wait(0);
  while( (parent =wait(&status)) > 0){
      printf("Exit = %d, child = %d\n", status/256, parent);
  }

  }

and the output is similar to:

    1, 21320
    2, 21321
    Exit = 0, child = 21321
    3, 21322
    Exit = 0, child = 21322
    4, 21323
    Exit = 0, child = 21323
    5, 21324
    Exit = 0, child = 21324

And I think that wait (0) does not wait for the entire subprocess, but only waits for the first exit and writes everything (Exit = ...).

Is there any way to do this:

    1, 21320
    2, 21321
    3, 21322
    4, 21323
    5, 21324

    Exit = 0, child = 21320
    Exit = 0, child = 21321
    Exit = 0, child = 21322
    Exit = 0, child = 21323
    Exit = 0, child = 21324

?

+4
source share
4 answers

Here's a demonstration of the easiest way to create output in the order you requested. It uses 3 cycles: one to create child processes, one to wait for them and collect their exit statuses, and the other to print exit statuses.

#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

#define NUMPROC 5

int main(void)
{
  pid_t child[NUMPROC];
  int status[NUMPROC];
  int i;

  printf("parent = %d\n", getpid());

  for(i=0;i<NUMPROC;++i) {
    if(fork() == 0) {
      sleep(i);
      printf("i=%d, %d\n",i, getpid());
      _exit(0);
    }
  }

  for(i=0;i<NUMPROC;++i)
    child[i] = wait(&status[i]);

  for(i=0;i<NUMPROC;++i)
    printf("Exit = %d, child = %d\n", WEXITSTATUS(status[i]), child[i]);
}
+4
source

wait(), - . , fork(), , . fork , , , , . .

, , , wait() IPC, POSIX, , , .


, , , wait() . wait, , , wait , .

+2

wait (0) , , , . pid-s for:

i_am_child = 0;
my_i = 0;
for (i = 0; i < nr_children; ++i) {
    child = fork ();
    if (child == 0) { i_am_child = 1; my_i = i; break; }
    childpid [i] = child;
}
if (i_am_child) {
    // do what children are supposed to do, e.g. printf and sleep (my_i)
    exit (0);
}
if (! i_am_child) // strictly, this line is not necessary, since children have exited
    for (i = 0; i < nr_children; ++i) waitpid (childpid [i], &status, 0);
...

, !

, break for fork .

+1

You're right. wait will return when any child comes out. If you want to wait until all the children exit, you can repeat the wait call in the while loop until it returns -1, and errno = ECHILD, which means that no more children exist.

while (! (wait (0) == -1 && errno == ECHILD) ) ;

This cycle is a little simplified. You apparently want to check the result of your processes, and you must handle other errors that may occur.

+1
source

Source: https://habr.com/ru/post/1531977/


All Articles