/* * Recursively compute the specified number. If print is * true, print it. Otherwise, provide it to my parent process. * * NOTE: The solution must be recursive and it must fork * a new child for each call. Each process should call * doFib() exactly once. */ static void doFib(int n, int doPrint) { // Kyung driving now int status1 = 0, status2 = 0; pid_t child1, child2; if(n == 0 || n == 1) { /* base case */ if(doPrint) { fprintf(stdout, "%d\n", n); } exit(n); } else { child1 = fork(); if(child1 == 0) { /* child process 1 */ doFib(n-1, 0); } wait(&status1); child2 = fork(); if(child2 == 0) { /* child process 2 */ doFib(n-2, 0); } wait(&status2); if(doPrint) { /* parent process */ fprintf(stdout, "%d\n", WEXITSTATUS(status1) + WEXITSTATUS(status2)); } exit(WEXITSTATUS(status1) + WEXITSTATUS(status2)); } // end of Kyung driving }
int main(int argc, char **argv) { int arg; int print; if(argc != 2){ fprintf(stderr, "Usage: fib <num>\n"); exit(-1); } if(argc >= 3){ print = 1; } arg = atoi(argv[1]); if(arg < 0 || arg > MAX){ fprintf(stderr, "number must be between 0 and %d\n", MAX); exit(-1); } doFib(arg, 1); return 0; }
/* * Recursively compute the specified number. If print is * true, print it. Otherwise, provide it to my parent process. * * NOTE: The solution must be recursive and it must fork * a new child for each call. Each process should call * doFib() exactly once. */ static void doFib(int n, int doPrint) { pid_t pid1; pid_t pid2; int status1; int status2; int x = 0; if(n <= 1) { if(doPrint) { printf("%d\n",n); } x = n; exit(x); } //child1 if((pid1 = fork()) == 0) { doFib(n-1,0); exit(x); } //child 2 if((pid2 = fork()) == 0) { doFib(n-2,0); exit(x); } //parent waitpid(pid1,&status1,0); waitpid(pid2,&status2,0); if(WIFEXITED(status1) && WIFEXITED(status2)) { x = WEXITSTATUS(status1) + WEXITSTATUS(status2); if(doPrint) { printf("%d\n",x); } exit(x); } }
// Max driving now static void doFib(int n, int doPrint) { pid_t pid = Fork(); int r; if (pid == 0) { if (n == 0 || n == 1) { exit(n); } else { pid_t pid1 = Fork(); pid_t pid2; int r1; int r2; if (pid1 != 0) { pid2 = Fork(); } if (pid1 == 0) { doFib(n-1, 0); } else if (pid2 == 0) { doFib(n-2, 0); } else { waitpid(pid1, &r1, 0); waitpid(pid2, &r2, 0); exit(WEXITSTATUS(r1) + WEXITSTATUS(r2)); } } } else { wait(&r); int status = WEXITSTATUS(r); if (doPrint) { printf("%d\n", status); } else { exit(status); } } }
/* * fork a new process to compute fib for n * parent proces will wait for the result and use it * as return value */ int doFibChild(int n) { pid_t cpid; int status; cpid = fork(); if (-1 == cpid) unix_error("fork failure"); if (0 == cpid){ /* code executed by child */ doFib(n, 0); } else{ /* code executed by parent */ if (-1 == waitpid(cpid, &status, 0)) unix_error("wait failure"); if (WIFEXITED(status)) /* status ok, get the return value from child */ return WEXITSTATUS(status); else unix_error("ERROR STATUS OF CHILD PROCESS"); } }