Wait()运行两次?

时间:2015-11-10 07:17:38

标签: c process wait

在我的下面的代码中,我运行了一个父进程,它会分成两个子进程。在 child(getpid()); 之后,两个孩子都退出状态。

然而,当我运行父进程时,它总是决定两次运行父节(设置两个不同的pid值),而我只是不能让它运行一次。获得一个值后有没有办法让等待停止?

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

void child(int n) { //n: child pid
  printf("\nPID of child: %i \n", n);

  //random number rand
  int randFile = open("/dev/random", O_RDONLY);
  int r;

  if(rand < 0)
    printf("ERROR: %s\n", strerror(errno));
  else {
    unsigned int seed;
    read(randFile, &seed, 4); //&rand is a pointer, 4 bytes
    int randClose = close(randFile);

    srand(seed); //seeds rand() with random from /dev/random
    r = rand();

    if(randClose < 0)
      printf("ERROR: %s\n", strerror(errno));

    //range between 5 and 20 seconds
    r = r % 20;
    if( r < 5)
      r = 5;
  }
  //  printf("\n%i\n", r);
  sleep(r);
  //  sleep(1);
  printf("\n child with pid %i FINISHED\n", n);

  exit( r );
}

int main() {
  printf("\nPREFORK\n");

  int parentPID = getpid();

  int child0 = fork();
  if(child0 < 0)
    printf("ERROR: %s\n", strerror(errno));

  int child1 = fork();
  if(child1 < 0)
    printf("\nERROR: %s\n", strerror(errno));

  if(getpid() == parentPID)
    printf("\nPOSTFORK\n");

  //if children
  if(child1 == 0) //using child1 as child-testing value b/c when child1 is set, both children are already forked
    child(getpid());

  int status;
  int pid = wait(&status);

  //parent
  if(getpid() != 0) {
    if( pid < 0)
      printf("\nERROR: %s\n", strerror(errno));
    if ( pid > 0 && pid != parentPID) {
      printf("\nPID of FINISHED CHILD: %i\n Asleep for %i seconds\n", pid, WEXITSTATUS(status));
      printf("PARENT ENDED. PROGRAM TERMINATING");
    }
  }
  return 0;
}

1 个答案:

答案 0 :(得分:2)

父母正在做:

int child0 = fork();  // + test if fork failed
int child1 = fork();  // + test if fork failed

首先你只有父母。 在第一个fork之后,您拥有父级和第一个子级,两个位于同一个执行点,所以就在下一个fork之前。 所以在此之后父母重新创建一个孩子,第一个孩子创建自己的孩子(并且将像父母一样)。

你必须使用if / else以确保孩子不会分叉。即:

child0 = fork();  // add check for errors
if (child0 == 0) {
  // the 1st child just have to call that
  child(getpid());
  exit(0);
}
// here we are the parent
child1 = fork();
if (child1 == 0) {
  // the 2nd child just have to call that
  child(getpid());
  exit(0);
}

你可以这样做,当然,这只是一个例子。重点是不要在孩子中召唤fork()