Problem with using Fork to write a Fibonacci program

I am implementing a fibonacci program with c++ by using fork() call.
I try to rewrite a example from github which write by python.
I think the programming language is similar just slight difference.

But my program does not work like the python approach.
I cannot figure out it since a long time ago.
Please point out which part Do I need to fix.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>

const int MAX = 13;

static void doFib(int n, int doPrint);
inline static void unix_error(char *msg);
static int exitcode(pid_t pid);
static void ret(int n, int doPrint);


int main(int argc, char **argv)
{
    int arg;
    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);
    }
    //1 is true.
    printf("%d\n", arg);
    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=0)
{
    pid_t pid1;
    pid_t pid2;
    int status1;
    int status2;
    if(n < 2) // Base case, exit back to parent?
    {
        ret(n, doPrint);
    }
    else // if not base case, fork child processes
    {
        pid1 = fork();
        if(pid1<0)
        {
            char message[] = "error.";
            unix_error(message);
        }else if(pid1==0)
        {
            printf("pid1==0, n-1= %d\n", n-1);
            doFib(n-1, 1);
        }
        pid2 = fork();
        if(pid2<0)
        {
            char message[] = "error.";
            unix_error(message);
        }else if(pid2 == 0)
        {
            printf("pid2==0, n-2= %d\n", (n-2));
            doFib(n-2, 1);

        }
        // Get value from child process 1
        status1 = exitcode(pid1);
        // Get value from child process 2
        status2 = exitcode(pid2);
        ret((status1+status2), doPrint);
    }
}

/*
 * unix_error - unix-style error routine.
 */
inline static void unix_error(char *msg)
{
    fprintf(stdout, "%s: %s\n", msg, strerror(errno));
    exit(1);
}

// Function to return exit code for PID
static int exitcode(pid_t pid)
{
    pid_t retpid;
    int status;
    //assert (retpid = pid && waitpid(pid, &status, 0));
    retpid =  waitpid(pid, &status, 0);
    if (pid != retpid && WEXITSTATUS(status))
    {
        printf("waitpid error\n");
    }
    return WEXITSTATUS(status);
}

static void ret(int n, int doPrint)
{
    if(doPrint==true)
        printf("%d\n",n);
    else
        exit(n);
}

This is the original approach which write by python.
I follow the idea and rewrite the program by c++.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/env python
#"""
#"""
import os
import sys

def exitcode(pid):
    retpid, status = os.waitpid(pid, 0)
    print 'status: ', status
    assert retpid == pid and os.WIFEXITED(status)
    print 'os.WEXITSTATUS(status)', os.WEXITSTATUS(status)
    return os.WEXITSTATUS(status)

def ret(f, doprint):
    print 'ret function: \n'
    if doprint:
        print "f:", f
        sys.exit()
    else:
        os._exit(f)

def fib(n, doprint=False):
    if n < 2: ret(n, doprint)
    print 'pid.fork'
    pid = os.fork()
    #print 'pid: ', pid
    #if pid: print 'pid=> ',pid
    if not pid: 
        print 'not pid 1: ', pid
        fib(n-1, False) # child 1
    pid2 = os.fork()
    #print 'pid2: ', pid2
    #if pid2: print 'pid2=> ',pid2
    if not pid2: 
        print 'not pid 2: ', pid
        fib(n-2, False) # child 2

    # parent
    ret(exitcode(pid) + exitcode(pid2), doprint)

# 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
fib(3, doprint=True) # 4 -> 13
Last edited on
Topic archived. No new replies allowed.