2012-02-16 62 views
2

我试图写递归使用叉中C.递归斐波那契在C(铂2)使用叉

这里,给定的intÑ计算所得的斐波纳契数的函数的功能是规范:如果doPrint为true,则打印它。否则,将其提供给父进程。解决方案应该是递归的,并且它必须为每个调用分派一个新的子节点。每个进程应该只调用一次doFib()。方法签名不能更改。帮助器功能不能使用。

这是这个问题的延续:Recursive Fibonacci using Fork (in C)

不幸的是,我从来没有想出了一个解决方案,在帖子的最后的问题,但是这是我修改后的代码。我想我已经明白了(伪码是明智的),但发现我仍然不确定几件。

在这一点上,这仅仅是为了我的娱乐。这不是家庭作业,并且不会再次在我的课程中覆盖(在最近通过的测试之后)。

static pid_t root_pid; 

// Function to return exit code for PID 
static int exitcode(pid_t pid) 
{ 
    pid_t retpid; 
    int status; 

    retpid = waitpid(pid, &status, 0); 
    if (pid != retpid) 
    { 
     printf("waitpid error\n"); 
    } 

    return WEXITSTATUS(status); 
} 

static void doFib(int n, int doPrint) 
{ 
    root_pid = getpid(); 

    pid_t pid1; 
    int status1; 

    pid_t pid2; 
    int status2; 

    if(n < 2) // Base case, exit back to parent? 
    { 
     exit(n); 
    } 
    else // if not base case, fork child processes 
    { 
     pid1 = fork(); 
     if (pid1 == 0) // Child Process 1 (for fib(n-1)) 
     { 
      doFib(n-1, doPrint); 
      exit(n-1); 
     } 
     else if (pid1 > 0) // Parent Process 
     { 
      pid2 = fork(); 
      if (pid2 == 0) // Child Process 2 (for fib(n-2)) 
      { 
       doFib(n-2, doPrint); 
       exit(n-2); 
      } 

      // Get value from child process 1 
      status1 = exitcode(pid1); 
      // Get value from child process 2 
      status2 = exitcode(pid2); 

      // When to print? 
      if (getpid() == root_pid) 
      { 
       int result = status1 + status2; 
       if (doPrint) 
       { 
        printf("%d\n", result); 
       } 
       else 
       { 
        exit(result); 
       } 
      } 
     } 
    } 
} 

的几个问题...

  1. 我需要调用这两个功能对于每个子进程?

    doFib(n-1, doPrint); exit(n-1); 
    
  2. 我的基本情况是否正确? (n < 2)
  3. 我的基本情况是否正确? (何时打印)

谢谢你的帮助。

+0

当你探索这个编码问题,你应该考虑的是一个斐波纳契问题的递归解决方案是获得结果的一种非常糟糕的方式,因为它效率非常低。 – Pointy 2012-02-16 15:03:02

+0

@积分欣赏两美分。这是我为完成中期课程而准备的一系列编码问题,我从来没有想过这个问题。我一直在打扰至少,但我相信这主要是为了教育目的。 – CODe 2012-02-16 16:37:51

回答

1

对于“何时打印”其实就是要你想打印......如果你只想打印最终的答案,那么你很可能需要一个标志,指示当你所在的答案根父进程,并使用if语句来测试您是否确实是根父级,以便只打印单个数字。另一方面,如果您希望打印整个序列直到最终号码,则不需要if声明。

例如,好的标志值将是根进程的PID。您可以将其保存在main()的第一对夫妇行中的名为root_pid的全局变量中,然后再开始分离单独的子进程。这样所有的子进程将具有为root_pid设置的相同值,并且if语句可以简单地为if (getpid() == root_pid)

所以做这样的事情:

//fib.c 
#include <unistd.h> 
pid_t root_pid 

int main() 
{ 
    root_pid = getpid(); 

    //... rest of your program 

} 

正如上面提到的,让你的if声明doFib内的以下内容:

if (getpid() == root_pid) 
{ 
    //...print results 
} 
else 
{ 
    exit(result) 
} 
+0

最终答案是我需要打印的,而不是序列。我曾想过我可能需要检测我是否是最终基本情况的根父级。你能否提供一些关于如何检测当前pid是否是root/top进程的代码示例?我GOOGLE了它无济于事。 – CODe 2012-02-16 13:32:53

+0

好的,我已经更新了一些代码示例 – Jason 2012-02-16 13:36:51

+0

谢谢,这看起来像是一个很好的解决方案,结束基地的情况下。非常感谢。现在希望有人可以找出其余的。 ;) – CODe 2012-02-16 13:46:20