操作系统实验----实验二 进程管道通信实验

操作系统的第二个实验是关于进程和线程间的通信的。我们实验的例子就是用线程来通信,线程间通信很简单,他们共有一些相同的资源。而且大一的学习用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;
}

转载于:https://www.cnblogs.com/sheling/archive/2012/07/17/2595755.html

1. 实验目的 1) 加深对进程概念的理解,明确进程和程序的区别。 2) 进一步认识并发执行的实质。 3) 分析进程争用资源的现象,学习解决进程互斥的方法。 4) 学习解决进程同步的方法。 5) 了解Linux系统中进程通信的基本原理。   进程操作系统中最重要的概念,贯穿始终,也是学习现代操作系统的关键。通过本次实验,要求理解进程的实质和进程管理的机制。在Linux系统下实现进程从创建到终止的全过程,从中体会进程的创建过程、父进程和子进程的关系、进程状态的变化、进程的互斥、同步机制、进程调度的原理和以管道为代表的进程的通信方式的实现。 2. 内容及要求:   这是一个设计型实验,要求自行编制程序。   使用系统调用pipe()建立一条管道,两个子进程分别向管道写一句话:   Child process1 is sending a message!   Child process2 is sending a message!   父进程管道读出来自两个子进程的信息,显示在屏幕上。   要求: 1) 父进程先接收子进程1发来的消息,然后再接收子进程2发来的消息。 2) 实现管道的互斥使用,当一个子进程正在对管道进行写操作时,另一子进程必须等待。使用系统调用lockf(fd[1],1,0)实现对管道的加锁操作,用lockf(fd[1],0,0)解除对管道的锁定。 3) 实现父子进程的同步,当子进程把数据写入管道后,便去睡眠等待;当父进程试图从一空管道中读取数据时,也应等待,直到子进程将数据写入管道后,才将其唤醒。 3.相关的系统调用 1) fork() 用于创一个子进程。 格式:int fork(); 返回值:在子进程中返回0;在父进程中返回所创建的子进程的ID值;当返回-1时,创建失败。 2) wait() 常用来控制父进程与子进程的同步。 在父进程中调用wait(),则父进程被阻塞,进入等待队列,等待子进程结束。当子进程结束时,父进程从wait()返回继续执行原来的程序。 返回值:大于0时,为子进程的ID值;等于-1时,调用失败。 3) exit() 是进程结束时最常调用的。 格式:void exit( int status); 其中,status为进程结束状态。 4) pipe() 用于创建一个管道 格式:pipe(int fd); 其中fd是一个由两个数组元素fd[0]和fd[1]组成的整型数组,fd[0]是管道的读端口,用于从管道读出数据,fd[1] 是管道的写端口,用于向管道写入数据。 返回值:0 调用成功;-1 调用失败。 5) sleep() 调用进程睡眠若干时,之后唤醒。 格式:sleep(int t); 其中t为睡眠时。 6) lockf() 用于对互斥资源加锁和解锁。在本实验中,该调用的格式为: lockf(fd[1],1,0);/* 表示对管道的写入端口加锁。 lockf(fd[1],0,0);/* 表示对管道的写入端口解锁。 7) write(fd[1],String,Length) 将字符串String的内容写入管道的写入口。 8) read(fd[0],String,Length) 从管道的读入口读出信息放入字符串String中。 4.程序流程 父进程: 1) 创建管道; 2) 创建子进程1; 3) 创建子进程2; 4) 等待从管道中读出子进程1写入的数据,并显示在屏幕上; 5) 等待从管道中读出子进程2写入的数据,并显示在屏幕上; 6) 退出。 子进程: 1) 将管道的写入口加锁; 2) 将信息“Child process n is sending message!”输入到变量OutPipe中,n=1,2; 3) 将OutPipe中信息写入管道; 4) 睡眠等待; 5) 将管道的写入口解锁; 6) 退出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值