zoukankan      html  css  js  c++  java
  • 操作系统实验实验二 进程管道通信实验

    操作系统的第二个实验是关于进程和线程间的通信的。我们实验的例子就是用线程来通信,线程间通信很简单,他们共有一些相同的资源。而且大一的学习用java线程实现多对多聊天也是很简单的。而进程之间的通信就必须通过消息传递或者共享内存来实现。这个实验就是使用无名管道来实现进程间信息的传递的。

    实验题目:

    设有二元函数f(x,y)=f(x)+f(y)

    其中: f(x)=f(x-1)*x   (x>1)

        f(x) =1  (x=1)

        f(y) = f(y-1) + f(y-2)  (y>2)

        f(y) = 1  (y=1,2)

    请编程建立3个并发协作进程,他们分别完成f(x,y)/f(y)/f(x)

    实验思路:利用无名管道通信,由于三个进程,先分别叫做fxy,fx,fy则fx要与fxy通信,使用一条管道,fy也要与fxy通信,使用另一条管道。除此之外无需其他通信。所以两条管道足够,在实验的时候周边很多同学第一反应都是三个管道,这实际上有点浪费了。

    实验代码及说明:

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
    {
        int pid,pid2;//进程号
        int pipe1[2]; //存放第一个无名管道标号
        int pipe2[2]; //存放第二个无名管道标号
        int fx,fy,fxy;
        int x,y;
        //接受用户输入
        printf("Please input x and y\n");
        scanf("%d %d",&x,&y);
        //使用 pipe()系统调用建立两个无名管道。建立不成功程序退出,执行终止
        if(pipe(pipe1) < 0){
            perror("pipe1 create failed");
            exit(EXIT_FAILURE);
        }
        if(pipe(pipe2) < 0){
            perror("pipe2 create failed");
            exit(EXIT_FAILURE);
        }
        //使用 fork()建立第一个子进程,不成功退出
        if((pid=fork()) <0){
            perror("process1 create failed");
            exit(EXIT_FAILURE);
        }
        else if(pid == 0){
            //第一个子进程负责从管道1的1端写
            close(pipe1[0]);
            //计算fx并输出到管道
            fx = Fx(x);
            printf("child pid is %d fx=%d (x=%d) \n",getpid(),fx,x);
            write(pipe1[1],&fx,sizeof(int));
            //读写完成后,关闭管道
            close(pipe1[1]);
            //子进程执行结束
            exit(EXIT_SUCCESS);
        }else{    //父进程
            //再创建一个子进程
            if((pid2=fork()) <0){
                perror("process2 create failed.");
                exit(EXIT_FAILURE);
            }else if (pid2 == 0){
                //管道2的1端写
                close(pipe2[0]);
                fy = Fy(y);
                printf("child pid is %d fy=%d (y=%d) \n",getpid(),fy,y);
                write(pipe2[1],&fy,sizeof(int));
                close(pipe2[1]);
                //退出该线程
                exit(EXIT_SUCCESS);
            }
            //父进程负责从管道1的0端,管道2的0端读
            close(pipe1[1]);
            close(pipe2[1]);
            read(pipe1[0],&fx,sizeof(int));
            read(pipe2[0],&fy,sizeof(int));
            fxy = fx + fy;
            printf("parent pid is %d fxy=%d (x=%d,y=%d) \n",getpid(),fxy,x,y);
            close(pipe1[0]);
            close(pipe2[0]);
        }
        //父进程执行结束
        return EXIT_SUCCESS;
    }
    //函数(xy)
    int Fxy(const int fx,const int fy){
        return fx+fy;
    }
    
    //函数f(y)
    int Fy(const int y){
        return y==1||y==2 ? 1:(Fy(y-1)+Fy(y-2));
    }
    //函数f(x)
    int Fx(const int x){
        return x==1? 1:Fx(x-1)*x;
    }
    文章来自 sheling 的博客园: http://www.cnblogs.com/sheling
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,
      且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    我的独立博客 http://blog.iyestin.com
  • 相关阅读:
    小朋友学数据结构(2):栈
    小朋友学数据结构(1):约瑟夫环的链表解法、数组解法和数学公式解法
    小朋友学C++(2)
    小朋友学C++(1)
    小朋友学C语言(8)
    小朋友学C语言(7)
    小朋友学C语言(6)
    小朋友学C语言(5):常量和变量,for循环
    小朋友学C语言(4):单精度浮点数与双精度浮点数
    小朋友学C语言(3):整数、浮点数、字符
  • 原文地址:https://www.cnblogs.com/sheling/p/2595755.html
Copyright © 2011-2022 走看看