进程间利用管道进行通信:打印斐波那契数列

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 
#include 
#include 
#include 
#include 
#include 
#include 
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;
}

你可能感兴趣的:(操作系统)