1

我很难理解子进程如何以及何时返回父进程。看看我使用各种网站放在一起的这个例子:

#include <stdio.h>
#include <stdlib.h>

main( int argc, char *argv[] )
{
   int i;
   int pid;
   int wpid;
   int status;

   time1.tv_sec = 5L;
   time1.tv_nsec = 0L;

   for ( i = 0; i < 10; i++ )
   {
      pid = fork();

      if ( pid < 0 ) {
         printf ( "Error" );
         exit ( 1 );
      }
      else if ( pid  == 0 ) {
         break;
      }
   }

   while ( ( wpid = wait ( &status ) ) > 0 )
   {
      printf ( "Exit status of %d was %d (%s)\n", ( int ) wpid, status, ( status == 0 ) ? "accept" : "reject" );
   }

   return 0;
}

我不明白孩子究竟返回了什么,何时/何地?在fork命令之后,孩子进入第二个循环,但它永远不会退出该循环以进一步向下并到达返回命令。我应该设置一个条件,所以只有父母执行那个循环吗?孩子会忽略wait()命令吗?

我发现这是一个问题,对于像我这样的人来说,经验丰富的程序员还不够笨拙。我找不到一个解决这个问题的答案。

4

4 回答 4

3

接收进程的wait退出代码,它是一个int. 该值可以设置,例如,通过exit(1)

您的代码如下

time1.tv_nsec = 0L; // only "parent" thread here.

for ( i = 0; i < 10; i++ )
{
  pid = fork();  // create a child.

  if ( pid < 0 ) {   //
     printf ( "Error" );
     exit ( 1 );
  }
  else if ( pid  == 0 ) { // only the child will enter this if, so it will exit the loop.
     break;
  }
}

 while ( ( wpid = wait ( &status ) ) > 0 )  // children and parent run this condition, but the
                                            // children don't have children so they will just
                                            // exit the wait function with -1, so they don't run
                                            // loop
 {
    printf ( "Exit status of %d was %d (%s)\n", ( int ) wpid, status, ( status == 0 ) ? "accept" : "reject" );  // only the parent executes this
 }

 return 0;   // return from main, this value is the one that will be received by the wait (in case
             // of children processes. There is also the option of using exit(0); exit ends program
             // execution everywhere it is used.
于 2013-11-11T23:20:53.133 回答
2

当你调用fork时,子进程父进程在同一个地方开始:就在调用fork. 唯一的区别是,fork子进程返回0,子进程的PID(>0)返回父进程。这就是为什么在调用fork.

因此,在您的子进程中,它将检查返回值 0 并中断,然后进入while循环。父进程将留在for循环中,在那里它将继续分叉子进程,直到它完成。然后它将进入while循环。

在您的子进程中,该wait()函数可能正在返回ECHILD(参见手册页),因为没有子进程,因此您应该确保子线程没有调用它或确保它们优雅地处理错误。

于 2013-11-11T23:31:08.940 回答
1

那么让我们来看看是如何fork()工作的。

fork被调用时,通过克隆调用它的进程来创建一个新进程。这个进程(从现在开始child)是第一个进程(进程)的精确副本。这意味着两个进程将继续在.fork()

现在,您如何区分哪个是父母,哪个是孩子?基于返回状态fork()

成功完成后,fork() 将向子进程返回 0,并将子进程的进程 ID 返回给父进程。

因此,如果我们假设一切正常并且没有发生错误,那么break;您的代码语句将在子进程中执行,并且父进程会继续产生子进程,直到循环结束。

现在,在break;每个孩子发现自己正在wait学习之后。从手册页wait()

wait, waitpid - 等待子进程停止或终止

但是等一下!每个子进程都没有要等待的子进程!所以wait()失败了ECHILD,孩子们终止了。

此外,在执行完所有循环迭代后,父进程会发现自己正在wait运行。父进程有几个子进程,并在它们终止时获取它们的退出状态。孩子不会以任何特定的顺序终止,这取决于操作系统,您不能假设一个会在另一个之前终止。

我希望以上内容能够澄清事情并现在能够修复您的代码以使其正常工作。

问候。

于 2013-11-11T23:25:07.457 回答
0

是的,您需要提供条件逻辑来指导子进程的工作。由于 fork 将设置父级的堆栈变量而不是子级的堆栈值,因此您可以执行以下操作:

 pid_t pid1 = 0;

 printf("*** Parent is about to fork process 1 ***\n");
 if ((pid1 = fork()) < 0) {
      printf("Failed to fork process 1\n");
      exit(1);
 }
 else if (pid1 == 0)
 {
      // Work of the child process
 }
 else 
 {
      // Work of the parent process
 }
于 2013-11-11T23:26:06.180 回答