在具有不同代码顺序的 Fibonacci 中的 fork() 函数期间出现奇怪的结果
Weird Result During the fork() function in Fibonacci with different Code Order
当我尝试使用 fork()
函数让子进程递归调用 doFib
时,我得到的奇怪结果是 sum1
和 sum2
属性在父进程中设置,但是当我想用它们来计算结果时,发现它们设置不正确。但是,如果我替换 pid2 = fork()
之前的第一个 while 循环,我可以获得正确的结果。谁能解释为什么会这样?
static void doFib(int n, int doPrint)
{
int result;
pid_t pid1;
int status1;
int sum1 = 0;
pid_t pid2;
int status2;
int sum2 = 0;
//printf("my pid is: %d\n", getpid());
//test for less number
if(n < 2)
{
if(doPrint)
{
printf("%d\n", n);
}
_exit(n);//result the value of F0 and F1
}
//not initial, need fork here
pid1 = fork();
if(pid1 == 0)
{//in children 1
doFib(n-1, 0);
}
pid2 = fork();
if(pid2 == 0){
doFib(n-2, 0);
}
while((pid1 = waitpid(-1, &status1, 0)) > 0){
if(WIFEXITED(status1))
sum1 = WEXITSTATUS(status1);
}
while((pid2 = waitpid(-1, &status2, 0)) > 0){
if(WIFEXITED(status2))
sum2 = WEXITSTATUS(status2);
}
result = sum1 + sum2;
if(doPrint)
{
printf("%d\n", result);
}else
{//in the children
_exit(result);
}
}
您对 waitpid
的 return 状态的检查不正确。成功时 return 是子进程的 pid,错误时是 -1。您不需要循环执行此操作。只做一次,成功就抓取return值
if ((pid1 = waitpid(-1, &status1, 0)) != -1) {
if(WIFEXITED(status1))
sum1 = WEXITSTATUS(status1);
}
if ((pid2 = waitpid(-1, &status2, 0)) != -1) {
if(WIFEXITED(status2))
sum2 = WEXITSTATUS(status2);
}
也就是说,递归地计算斐波那契数是低效的,尤其是当通过分叉完成递归时。这也将 return 的数量限制为 255,因为进程的 return 值只有一个字节宽。
当我尝试使用 fork()
函数让子进程递归调用 doFib
时,我得到的奇怪结果是 sum1
和 sum2
属性在父进程中设置,但是当我想用它们来计算结果时,发现它们设置不正确。但是,如果我替换 pid2 = fork()
之前的第一个 while 循环,我可以获得正确的结果。谁能解释为什么会这样?
static void doFib(int n, int doPrint)
{
int result;
pid_t pid1;
int status1;
int sum1 = 0;
pid_t pid2;
int status2;
int sum2 = 0;
//printf("my pid is: %d\n", getpid());
//test for less number
if(n < 2)
{
if(doPrint)
{
printf("%d\n", n);
}
_exit(n);//result the value of F0 and F1
}
//not initial, need fork here
pid1 = fork();
if(pid1 == 0)
{//in children 1
doFib(n-1, 0);
}
pid2 = fork();
if(pid2 == 0){
doFib(n-2, 0);
}
while((pid1 = waitpid(-1, &status1, 0)) > 0){
if(WIFEXITED(status1))
sum1 = WEXITSTATUS(status1);
}
while((pid2 = waitpid(-1, &status2, 0)) > 0){
if(WIFEXITED(status2))
sum2 = WEXITSTATUS(status2);
}
result = sum1 + sum2;
if(doPrint)
{
printf("%d\n", result);
}else
{//in the children
_exit(result);
}
}
您对 waitpid
的 return 状态的检查不正确。成功时 return 是子进程的 pid,错误时是 -1。您不需要循环执行此操作。只做一次,成功就抓取return值
if ((pid1 = waitpid(-1, &status1, 0)) != -1) {
if(WIFEXITED(status1))
sum1 = WEXITSTATUS(status1);
}
if ((pid2 = waitpid(-1, &status2, 0)) != -1) {
if(WIFEXITED(status2))
sum2 = WEXITSTATUS(status2);
}
也就是说,递归地计算斐波那契数是低效的,尤其是当通过分叉完成递归时。这也将 return 的数量限制为 255,因为进程的 return 值只有一个字节宽。