fork两个子进程,一个计算N的和和另一个N的阶乘

时间:2018-02-07 10:03:05

标签: c unix fork

我必须从命令行获取一个整数参数。创建两个子进程。第一个计算正整数之和,第二个计算阶乘。父母也必须等待每个孩子完成,然后父母用自己的标识符打印出“完成”。

输出示例是

[ID = 101] Sum of positive integers up to 5 is 15
[ID = 102] Factorial of 5 is 120
[ID = 100] Done

但我得到的输出是

 [ ID = 4262] Factorial of 5 is 120
[ID = 4262] DONE
[ID = 4260] DONE
[ ID = 4261] sum of positive integers up to 5 is 15

这是我的代码

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

int main (int argc, char * argv[])
{
pid_t ret;
int i, num,sum=0,fact=1;

ret=fork();
    for(i=1;i<argc; i++){
        num=atoi(argv[1]);

    }
if (ret == 0) {
    for(i=1;i<=num;i++){
    sum+=i;
    }
    printf("\n [ ID = %d] sum of positive integers up to %d is %d\n",getpid(),num,sum);
}

else{
    if(fork()==0){
    for(i=1;i<=num; i++){
        fact*=i;    
    }printf("\n [ ID = %d] Factorial of %d is %d\n",getpid(),num,fact);
    }
    wait(NULL);
    printf("\n[ID = %d] DONE",getpid());
}

return 0;
}

我的问题是我不确定如何正确分叉以拥有2个子进程。

2 个答案:

答案 0 :(得分:2)

我建议您先创建两个独立的函数sum()fact(),以实现每个子进程应执行的任务:

void sum(int num) { /* ... */ }
void fact(int num) { /* ... */ }

然后,指针函数引用这些函数:

typedef (*child_task_t)(int);

child_task_t child_task[2];
child_task[0] = sum;
child_task[1] = fact;

这样,您可以通过fork()循环轻松地for生成两个孩子:

for (int i = 0; i < 2; i++) {
   switch(fork()) {
   case 0: // parent
      continue;
   case -1: // error
      return -1;
   default: // child
      task_child[i](num); // <-- run the task
      exit(0); // child process finishes
   }
}

// parent waits for the children to finish
for (int i = 0; i < 2; i++)
   wait(NULL);

答案 1 :(得分:0)

您的代码中存在一些问题,我对其进行了评论:

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

int main (int argc, char * argv[])
{
    pid_t ret;
    int i, num,sum=0,fact=1;

    ret=fork();
    for (i=1; i < argc; i++) {
        num = atoi(argv[1]);
    }
    if (ret == 0) 
    {
        /* in first child */
        for(i=1;i<=num;i++){
            sum+=i;
        }
        printf("\n [ ID = %d] sum of positive integers up to %d is %d\n",getpid(),num,sum);
        /* here, you should exit from first child 
           with exit or return */

    }
    else
    {
        /* here, we are in parent */
        if(fork()==0)
        {
            /* here, in second child */
            for(i=1;i<=num; i++){
                fact*=i;    
            }
            printf("\n [ ID = %d] Factorial of %d is %d\n",getpid(),num,fact);
            /* here, you should exit from second child 
                with exit or return */

        }

        /* warning, second child and parent get there */
        /* warning, here you only wait for one child */
        wait(NULL);
        printf("\n[ID = %d] DONE",getpid());
    }

    return 0;
}

简化它很容易:

  • 隔离孩子的代码
  • 确定父母或子女将执行哪一行
  • 等待孩子


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

int main (int argc, char * argv[])
{
    pid_t ret;
    int i, num,sum=0,fact=1;

    /* get parameter (you should test the value of argc before) */
    num = atoi(argv[1]);    

    /* create a first child */
    if (0 == fork()) 
    {
        /* in first child */
        for(i=1;i<=num;i++){
            sum+=i;
        }
        printf("\n [ ID = %d] sum of positive integers up to %d is %d\n",getpid(),num,sum);

        /* exit from first child */
        exit(0);    
    }

    /* this point will not be reached by first child */

    /* create a second child */
    if ( 0 == fork())
    {
        /* here, in second child */
        for(i=1;i<=num; i++){
            fact*=i;    
        }
        printf("\n [ ID = %d] Factorial of %d is %d\n",getpid(),num,fact);
        /* exit from second child */
        exit(0);           
    }

    /* this point will not be reached by second child */

    /* wait for one child */
    wait(NULL);

    /* wait for a second child */
    wait(NULL);

    printf("\n[ID = %d] DONE",getpid());

    return 0;
}