操作系统实验二、进程通信实验——f(x,y) = f(x) + f(y)

问题描述

设有二元函数 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(x)、f(y)

示例程序

使用实验示例程序应实现一个并发的父子程序合作将整数 1 从 1 累加到 10 的功能。
打开命令行终端,新建一个文件夹。
命令:cd 创建路径
Mkdir myfirst3
在新建文件夹中建立以下名为 ppipe.c 的 的 C 语言程序
命令:vi ppipe.c
在这里插入图片描述建立项目管理文件 Makefile(其实后面会发现这个文件不建也可以)
在这里插入图片描述命令生成 ppipe.o 文件
在这里插入图片描述生成 ppipe 执行文件
在这里插入图片描述执行 pctl 程序
在这里插入图片描述

独立实验

请编程建立 3 个并发协作进程,它们分别完成 f(x,y)、f(x)、f(y)
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],f[y],f[x]+f[y],所以这里分别使用 3 个进程来进行这里的控制,首先创建一个子进程 1,用于计算 f[x],在父进程中再次创建一个子进程用于计算 f[y],由于程序的并发执行,可以分别设置两个管程,保证二者之间是互斥的,最后将二者相加即可。
pipe.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int f1(int x)
{
if(x==1)
{
return 1;
}
else
{
return f1(x-1)*x;
}
}
int f2(int y)
{
if(y ==1||y==2)
{
return 1;
}
else
{
return f2(y-1)+f2(y-2);
}
}
int main(int argc,char* argv[])
{
int x,y;
printf("Input x,y\n");
scanf("%d %d",&x,&y);
int pid1,pid2;
int pipe1[2];
int pipe2[2];
int pipe3[2];
int pipe4[2];
if(pipe(pipe1)<0)
{
printf("pipe1 error");
}
if(pipe(pipe2)<0)
{
printf("pip2 error");
}
if(pipe(pipe3)<0)
{
printf("pipe3 error");
}
if(pipe(pipe4)<0)
{
printf("pipe4 error");
}
if((pid1=fork())<0)
{
perror("pipe not create");
}
else if(pid1==0)
{
close(pipe1[1]);
close (pipe2[0]);
int x1;
read(pipe1[0],&x1,sizeof(int));
int z=f1(x1);
write(pipe2[1],&z,sizeof(int));
close(pipe1[0]);
close(pipe2[1]);
exit(0);
}
else
{
//Father process
if((pid2=fork())<0)
{
perror("Process not create ");
exit(EXIT_FAILURE);
}
else if(pid2==0)
{
close(pipe3[1]);
close(pipe4[0]);
int y1;
read(pipe3[0],&y1,sizeof(int));
int z=f2(y1);
write(pipe4[1],&z,sizeof(int));
close(pipe3[0]);
close(pipe4[1]);
exit(0);
}
close(pipe1[0]);
close(pipe2[1]);
close(pipe3[0]);
close(pipe4[1]);
int z;
write(pipe1[1],&x,sizeof(int));
write(pipe3[1],&y,sizeof(int));
read(pipe2[0],&x,sizeof(int));
read(pipe4[0],&y,sizeof(int));
z=x+y;
printf("the result is %d\n",z);
close(pipe1[1]);
close(pipe2[0]);
close(pipe3[1]);
close(pipe4[0]);
}
return 0;
}

运行
在这里插入图片描述小结
管程在功能上和信号量及 PV 操作类似,属于一种进程同步互斥工具,但是具有与信号量及 PV 操作不同的属性。管道以半双工方式工作,即它的数据流是单方向的。因此使用一个管道一般的规则是读管道数据的进程关闭管道写入端,而写管道进程关闭其读出端。

父进程和子进程通过返回值是否为 0 来进一步标识,二者并发运行,具体方式有操作系统的内部调度完成,父进程和子进程交替输出的形式是并发和管程控制的共同结果。另外在计算 f[x]和 f[y]时采用调用函数的形式也显得更加清晰。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页