進程間利用管道進行通信:打印斐波那契數列

Fibonacci序列是0, 1, 1, 2, 3, 5, 8, .... ,通常它可以表示爲:

f ib0 = 0

f ib1 = 1

f ibn= f ibn1 + f ibn2

編寫一個C程序,使用系統調用fork()創建兩個子進程P1P2。他們的任務如下:

1)       子進程P1打印自己的pid,然後使用exec(族)系統調用顯示當前目錄下文件和子目錄的詳細信息。

2)       子進程P2中生成Fibonacci序列,序列的個數在程序命令行中作爲參數傳入,例如,參數爲7,則子進程P2生成的Fibonacci序列爲01235813。通過某種進程通信機制(共享內存、管道、消息等IPC機制),子進程P2把生成的Fibonacci序列發送給父進程,並由父進程輸出(打印)Fibonacci序列。在父子進程通信的過程中必須實現同步,以使在子進程完成生成序列之前,父進程不會輸出Fibonacci序列。使用wait()系統調用可以實現進程間的簡單同步。執行必要的錯誤檢查以保證不會接受命令行參數傳遞來的負值。


採用fork()創建進程,進程在創建的時候共享了父進程的所有資源,包括PC程序計數器,這時候父子進程的程序計數器都是pid=fork()的等號上,也即MOVE操作上,只不過返回的值在內核代碼中區分了返回的不同,父進程得到了>0的一個Pid_t,子進程爲0.

通過pipe命令,利用管道進行通信

#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
int main(int argc,const char* argv[])
{
    if(argc != 2)  //防止報錯
    {
        printf("please cin a number :%s\n",argv[0]);
        exit(EXIT_SUCCESS);
    }
    pid_t childpid1,childpid2;
    int pfd[2];//管道
    int n = atoi(argv[1]); //獲得參數
    childpid1 = fork();
    if( childpid1 < 0)
    {
        perror("fork_child1");
        exit(EXIT_FAILURE);
    }
    else if( childpid1 == 0)
    {
        printf("childpid1 is:%d",getpid());
        execlp("/bin/ls", "/bin/ls", "-R", ".", NULL);
    }
    else
    {
        pipe(pfd);
        wait(NULL);
        childpid2 = fork();
        if(childpid2  < 0)
        {
            perror("fork_child2");
            exit(EXIT_FAILURE);
        }
        else if( childpid2 == 0)
        {
            int next = 1;
            int now = 0;
            int tmp = 0;
            int i;
            close(pfd[0]);
            for(i = 0; i < n; i++)
            {
                write(pfd[1],&now,sizeof(now));
                tmp = now;
                now = next;
                next += tmp;
            }
        }
        else
        {
            wait(NULL);
            close(pfd[1]);
            int i;
            int status;
            for(i = 0; i < n-1; i++)
            {
                int ret;
                ret = read(pfd[0],&status,sizeof(status));
                if(ret < 0)
                {
                    perror("read");
                    exit(EXIT_FAILURE);
                }
                printf("%d、",status);
            }
            int ret = read(pfd[0],&status,sizeof(status));
            if(ret < 0)
            {
                perror("read");
                exit(EXIT_FAILURE);
            }
            printf("%d\n",status);
        }
    }
    return EXIT_SUCCESS;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章