【问题标题】:Fork() to performe different processesfork() 执行不同的进程
【发布时间】:2015-04-28 15:22:02
【问题描述】:

我正在尝试使用多个 fork() 调用来创建几个具有不同任务的孩子 我找到了一个代码 Multiple child process

这真的很接近我想要的,但我无法完全理解它

pid_t firstChild, secondChild;
firstChild = fork();
if(firstChild != 0)
{
  // In parent
  secondChild = fork();
  if(secondChild != 0)
  {
    // In parent
  }
  else
  {
    // In secondChild
  }
}
else
{
  // In firstChild
}

我的问题是:

  • 已经创建了多少进程(我假设我们有 4 个,因为它是 2 个分叉!)?
  • 在这部分代码中

firstChild = fork();
if(firstChild != 0)
{
    // In parent
    secondChild = fork();
    if(secondChild != 0)
    {
        // In parent
    }

“//in parent”是否意味着它们都是同一个进程(当我尝试测试时它们具有相同的 PID)。

  • 如何使用 2 个叉子创建 3 个子节点?(我可以画出以 4 个叶子结尾的树,其中 3 个是子节点和 1 个父节点)

谢谢(如果我没有完全理解 Fork 的概念,请随时告诉我)

【问题讨论】:

    标签: c unix fork task children


    【解决方案1】:

    以下代码展示了如何创建 4 个进程(1 个父 3 个子),只有 2 个分叉

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    
    int *list;
    
    void calculate_average(int );
    void calculate_maximum(int);
    void calculate_minimum(int);
    
    void calculate_average(int count) 
    {
            int i, total = 0;
    
    
            for (i = 0; i < count; i++)
                    total += list[i];
    
            double average = total / count;
            
    	printf("average is %f\n",average);
    
    }
    
    void calculate_maximum(int count)
    {
            int i;
    
            int maximum = list[0];
    
            for (i = 1; i < count; i++)
                    if (list[i] > maximum)
                            maximum = list[i];
    
    	printf("maximum is %d\n",maximum);
    }
    
    void calculate_minimum(int count)
    {
            int i;
    
            int minimum = list[0];
    
            for (i = 1; i < count; i++)
                    if (list[i] < minimum)
                            minimum = list[i];
    	printf("minimum is %d\n",minimum);
    }
    
    int main(int argc, char *argv[])
    {
    	pid_t pid, pid1;
    
    	int num_of_args = argc-1;
    	int i;
    
    	/* allocate memory to hold array of integers */
            list = malloc(sizeof(int)*num_of_args);
    
            for (i = 0; i < num_of_args; i++)
                    list[i] = atoi(argv[i+1]);
            
    	printf("The %d number of input ingeters are\n",num_of_args);
            for (i = 0; i < num_of_args; i++)
                    printf("%d\n",list[i]);
    
    	/* fork a child process */
    	pid = fork();
    
    	if (pid < 0) { /* error occurred */
    		fprintf(stderr, "Fork Failed\n");
    		return 1;
    	}
    	else if (pid == 0) { /* P2 */
    		pid1=getppid();
    		calculate_average(num_of_args);
    	}
    
    	else { 		/* P1 */
    		pid1=getpid();
    		wait(NULL);
    	}
    	
     	pid = fork();
    	
    	if (pid < 0) { /* error occurred */
    		fprintf(stderr, "Fork Failed\n");
    		return 1;
    	}
    	
    	else if (pid == 0) { /* could be either P3 or P4 */
    		if (getppid() == pid1) { /* P3 */
    			calculate_minimum(num_of_args);
    		}	
    
    		else {  /* P4 */
    			calculate_maximum(num_of_args);
    		}
    	}
    	
    	else { 
    		wait(NULL);
    	}
        
        	return 0;
    }

    请注意,其中一个孩子将成为孙子的父母

    【讨论】:

      【解决方案2】:

      已经创建了多少进程(我假设我们有 4 个,因为它是 2 个分叉!)?

      根据您的forks 的结果,它应该是 0 到 2。如果没有任何问题,可能是 2。有一个父进程派生出 2 个子进程。

      “//in parent”是否意味着它们都是同一个进程(当我尝试测试时它们具有相同的 PID)。

      是的。在您的情况下,代码正在检查 fork 的返回值是否非零。这不是一个好主意,因为它涵盖了两种不同的情况:

      • 它可能小于零表示错误,或者...
      • 它可能大于零,向父进程指示新生成进程的pid 无论如何...考虑到一切顺利并且两个分叉都成功了,您最终会得到一个拥有 2 个不同子进程的父进程。

      如何使用 2 个叉子创建 3 个孩子?(我可以画出以 4 个叶子结尾的树,其中 3 个是孩子,1 个是父母

      这样的事情应该可以解决问题:

      firstChild = fork();
      if (firstChild < 0) {
          exit(EXIT_FAILURE);
          perror("fork");
      }
      secondChild = fork();
      

      请注意,通过不再检查 fork() 的返回值,我得到了一个子进程继续在与父进程相同的位置执行。因此,下一次分叉实际上将由父进程和子进程执行,每个子进程都会产生一个新进程。所以我会得到这样的东西......

      parent─┬─child1───(child1's child)
             └─child2
      

      我想不出任何方法可以只用 2 个叉子得到这个:

      parent─┬─child1
             ├─child3
             └─child2
      

      注意:stackoverflow 的习惯是每个主题只回答一个问题。

      【讨论】:

      • 非常感谢您,很抱歉给您带来不便,还有一个问题,因为孩子 1 既是父母又是孩子,当我使用 (firstChild!=0) 和 I在父进程还是子进程中?
      • @user3382285 我不确定我是否理解你上面的问题 - 你能改写一下吗?... firstChild!=0 检查将帮助你区分你的 parent/child1 代码 (>0 --> 父级,==0 --> child1).
      • 当我使用像你一样具有 Fork() fork() 的代码时 firstChild = fork(); if (firstChild
      • 总共将有 4 个进程(但其中只有 3 个是由 fork 创建的 - 参见上面类似 pstree 的输出)。当然……如果您想查看它们的 PID,只需在 forks 之后添加那些 printfs
      • 但我不知道如何让他们做不同的事情(printf 工作是因为我使用了 getpid() 。如果我想让他们做不同的功能呢。就像代码中的问题为每个孩子提供了包含您自己的代码/功能的空间,并且只有孩子会执行它。
      猜你喜欢
      • 2014-06-17
      • 1970-01-01
      • 2012-12-16
      • 2019-02-22
      • 1970-01-01
      • 2020-11-24
      • 2011-06-27
      • 2023-03-20
      • 1970-01-01
      相关资源
      最近更新 更多