在前面,我欣然承认这是作业。但是我一直在撞墙撞墙,我只是不明白。赋值参数如下:“递归计算指定的数字。如果print为true,则打印它。否则,将其提供给我的父进程。
注意:解决方案必须是递归的,并且必须为每个调用分叉一个新子节点。每个流程都应该只调用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);
}
Fibonacci是我教过的第一个递归的例子之一,我在基层理解它。但是,当我运行我的程序时,使用10作为给定的参数(尽管任何参数产生不正确的结果),我得到一个垃圾流,结尾于:-1861761537
(这些负数很多),17。我所做的更改导致不同的垃圾值,但最终仍然是17。
我认为问题在于我使用waitpid,但我不知道它会是什么。假设这是我错误的来源,我是否正确?我仔细阅读了教科书,手册页,互联网等,我不知道我能解决什么问题。任何帮助将不胜感激。谢谢。
答案 0 :(得分:3)
在为+=
&amp;分配值时,您使用=
分配而不是sum1
分配来自sum2
的{{1}}。因为WEXITSTATUS()
&amp; sum1
从未初始化,这为您的程序创建了垃圾数据的插入向量。
同样在Zack中指出comments,
由于退出状态最大值为sum2
,代码将无法在Unix计算机上运行,因为值n >= 15
。
答案 1 :(得分:1)
我会抓住这个:
exit(n-1);
为什么要将输入减少为退出值?如果我正确地读取代码的意图,退出值应该是中间结果
:)由于这是作业,我不会给你答案。此外,因为我不知道答案,所以在很长一段时间内没有使用过fork()。
相反,将答案视为模式替换:
编写第一个模式并测试它,然后用第二个模式转换它。至少有两个正确的解决方案。找到两个。
答案 2 :(得分:0)
您需要做的是调试程序。我建议先给它一个简单的执行路径,看看它做了什么。例如,从n = 1开始,然后n = 2,然后n = 3。注释掉第二个代码并专注于让第一部分工作。利用print语句检查程序中不同点的变量值 - 这将为您提供有关如何工作的线索。