2

在前面,我欣然承认这是功课。但是我一直把头撞在墙上,我就是不明白。赋值参数如下:“递归计算指定数。如果print为真,则打印。否则,提供给我的父进程。

注意:解决方案必须是递归的,并且必须为每个调用派生一个新的孩子。每个进程应该只调用doFib()一次。”

这是我第一次使用 fork(),虽然我想我理解,但我无法理解为什么我没有得到正确答案。这是我的代码,相当简陋:

doFib(int n, int doPrint)
{
    int status;
    int print;
    pid_t pid1;
    pid_t pid2;
    int sum1;
    int sum2;

    if (n < 2)
        exit(n);

    pid1 = fork();

    if (pid1 == 0)
    {
        doFib(n-1, doPrint);
        exit(n-1);
    }

    pid2 = fork();

    if (pid2 == 0)
    {
        doFib(n-2, doPrint);
        exit(n-2);
    }

    while ((pid1 = waitpid(-1,&status, 0)) >0)
    {
        if(WIFEXITED(status))
            sum1 += WEXITSTATUS(status);
    }

    while ((pid2 = waitpid(-1,&status, 0)) >0)
    {
        if(WIFEXITED(status))
            sum2 += WEXITSTATUS(status);
    }

    print = sum1 + sum2;

    if(doPrint)
        printf("%d\n", print);
    else
        exit(0);
}

斐波那契是我学习的第一个递归示例之一,我在基本层面上理解它。但是,当我运行程序时,将 10 作为给定参数(尽管任何参数都会产生不正确的结果),我得到一个以以下结尾的垃圾流:(-1861761537有很多这样的负数),17。我所做的任何更改都会导致不同的垃圾值,但最终仍为 17。

我相信问题在于我使用了waitpid,但我不知道它会是什么。我是否正确假设这是我的错误的根源?我搜索了教科书、手册页、互联网等,但我不知道我能解决什么问题。任何帮助将不胜感激。谢谢你。

4

3 回答 3

3

在将值分配给& from时,您使用+=了赋值而不是赋值。因为&从未被初始化,这为你的程序中的垃圾数据创建了一个插入向量。=sum1sum2WEXITSTATUS()sum1sum2

同样正如Zack在评论中指出的那样,由于n >= 15退出状态最大值为255.

于 2013-09-13T22:33:29.683 回答
1

我会尝试一下:

 exit(n-1);

你为什么要减少输入作为退出值?如果我正确阅读了代码的意图,则退出值应该是中间结果

附录

:) 因为这是作业,我不会给你答案。另外,由于我不知道答案,所以很长时间没有使用 fork() 了。

相反,将答案视为模式替换:

  1. 第一个模式是一个普通的递归 Fib 函数,具有同步调用
  2. 第二种模式是从异步分叉而不是同步调用中检索结果

编写第一个模式并对其进行测试,然后用第二个模式对其进行转换。至少有两个正确的解决方案。找到两者。

于 2013-09-13T21:59:04.907 回答
0

你需要做的是调试你的程序。我建议先给它一个简单的执行路径,然后看看它做了什么。例如,从 n=1 开始,然后 n=2,然后 n=3。注释掉第二个 fork 代码并专注于让第一部分工作。利用 print 语句检查程序中不同点的变量值——这将为您提供有关它如何工作的线索。

于 2013-09-14T15:21:11.717 回答