C:Fork()中的Recusive Fibonacci,我非常接近

时间:2017-09-29 03:09:21

标签: c recursion fork fibonacci

我试图实现一个递归的Fibonacci程序,该程序使用fork()和消息队列,使用getopt设置命令行选项以打印第n个Fibonacci数字和' m'计算门槛。我的程序差不多完了,但我的输出有问题。我的一个条件似乎正常工作,但另一个似乎尝试输出两个条件。我相信这是因为fork()的属性,我是新手。这是否发生是因为我们不知道子进程何时产生?任何可以使用的指导,提示,技巧或信息都将非常感谢!

生成文件:

    # make all: compiles and links all files
    # make test1: runs executable for prob1 (n=6 m=6)
    # make test2: runs executable for prob1 (n=6 m=3)
    # make clean: cleans up .o and *~ files
    #
    # Options:
    #   -F => nth sequence
    #   -S => computing threshold
    #
    ################################################################################    

    CC = gcc
    CFLAGS = -g -Wall -Werror -c
    OBJ = main.o fib_seq.o

    ################################  Make All  ####################################

    # Compiles all files
    all: main fib_seq
        $(CC) $(OBJ) -o myfib

    # Compiles object files
    main: main.c
        $(CC) $(CFLAGS) $@.c

    fib_seq: fib_seq.c
        $(CC) $(CFLAGS) $@.c

    ################################ Test ##########################################

    test1: myfib
        ./myfib -F 6 -S 6

    test2: myfib
        ./myfib -F 6 -S 3

    #############################  Clean  ##########################################

    clean:
        $(RM) *.o *~ myfib* $(SO)

主要

    #include <stdlib.h>
    #include <stdio.h> 
    #include <unistd.h> 
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/shm.h> 
    #include <sys/stat.h> 

    int fib_seq(int x);

    int main(int argc, char **argv)  
    {
        // Definitions
        int x=0, fib=0;
        int c, n, m, i;
        int Fflag, Sflag; 
        pid_t pid; 

        // interprocess communication
        const int size=4096; 
        char *shared_memory; 

        int segment_id=shmget(IPC_PRIVATE, size, S_IRUSR|S_IWUSR);
        shared_memory= (char *)shmat(segment_id, NULL, 0); 

        // command line options using getopt for -F and -S
        while ((c=getopt(argc, argv, "F:S:")) != -1) 
            switch(c) 
            {
                case 'F':
                    Fflag = 1;
                    //printf("test\n");
                    n = atoi(optarg);
                    break;
                case 'S':
                    Sflag = 1;
                    m= atoi(optarg);
                    printf("\nn = %d\nm = %d\n", n, m);
                    break;
                default:
                    abort();
            }

        //begin fibonacci sequence
        for(i=0; i<=n; i+=1) {

            fib = fib_seq(x);
            x+=1;

            // fork child to compute next Fib numbers recursively
            //if((((x-1)>m)&&((x-2)>m))) {
            if((x-1)>m) {
                pid=fork();
                if (pid < 0) {
                    fprintf(stderr, "Fork failed");
                    return 1;
                }
                if (pid == 0) {
                    printf("\nChild computing next Fib number...\n");
                    fib = fib_seq(x); 
                    printf("Child process complete\n");
                }
                else {
                  printf("\nParent waiting for child to finish...\n");
                  wait(NULL);
                }
                return 0;
            }
            // compute next fib numbers recursively
            //else if((((x-1)<=m)&&((x-2)<=m))) {
            else if((x-1)<=m) {
                printf("\nComputing without child...");
                fib = fib_seq(x-1);
            }
            printf("\nFibonacci sequence of %d is %d\n", x-1, fib);
        }
        return 0;
    }

fib_seq:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>

    int extern x;

    int fib_seq(int x) { 

         int i, rint = (rand() % 30); 
         double dummy; 

         for (i = 0; i<rint*100; i++) { 
           dummy = 2.3458*i*8.7651/1.234;
         }

         if (x == 0) 
            return(0);
         else if (x == 1) 
            return(1); 
         else 
            return fib_seq(x-1)+fib_seq(x-2);
    }

输出1:

    n = 6
    m = 6

    Computing without child...
    Fibonacci sequence of 0 is 0

    Computing without child...
    Fibonacci sequence of 1 is 1

    Computing without child...
    Fibonacci sequence of 2 is 1

    Computing without child...
    Fibonacci sequence of 3 is 2

    Computing without child...
    Fibonacci sequence of 4 is 3

    Computing without child...
    Fibonacci sequence of 5 is 5

    Computing without child...
    Fibonacci sequence of 6 is 8

输出2:

    n = 6
    m = 3

    Computing without child...
    Fibonacci sequence of 0 is 0

    Computing without child...
    Fibonacci sequence of 1 is 1

    Computing without child...
    Fibonacci sequence of 2 is 1

    Computing without child...
    Fibonacci sequence of 3 is 2

    Parent waiting for child to finish...

    Child computing next Fib number...
    Child process complete

1 个答案:

答案 0 :(得分:0)

fork()通过复制调用进程来创建新进程。 我建议你详细阅读fork()。

回到您的计划,您只需在程序中进行一些更正即可使其正常工作。

更正号码1 -

在子进程中将x-1而不是x传递给fib_seq()。

更正号码2 -

等待(NULL)(父级等待子级)之后,您已从main()返回父进程 -

return 0;

这将退出父进程,因此每当子进程生成时,父进程将在子进程完成后退出。

在if(pid == 0)块中移动上面的return语句并添加printf以写入在子进程中执行的fib_seq()函数返回的fib值。

    if (pid == 0) {
        printf("\nChild computing next Fib number...\n");
        fib = fib_seq(x-1);
        printf("\nFibonacci sequence of %d is %d\n", x-1, fib);
        printf("Child process complete\n");
        return 0;
    }

更正号码3 -

现在,如果子进程正在计算系列的下一个值,则父进程不需要计算系列的下一个值。 因此,在wait()之后在父级中添加“continue”。 程序的一部分看起来像 -

 if (pid == 0) {
     printf("\nChild computing next Fib number...\n");
     fib = fib_seq(x-1);
     printf("\nCHILD Fibonacci sequence of %d is %d\n", x-1, fib);
     printf("Child process complete\n");
     return 0;
 }
 else {
     printf("\nParent waiting for child to finish...\n");
     wait(NULL);
     continue;
 }