山东大学软件学院操作系统实验二——进程通信实验
文章目录一、实验时间二、实验内容三、示例实验四、本次实验一、实验时间2021年4月22日,星期四,第8周二、实验内容通过Linux 系统中管道通信机制,加深对于进程通信概念的理解,观察和体验并发进程间的通信和协作的效果 ,练习利用无名管道进行进程通信的编程和调试技术。管道pipe是进程间通信最基本的一种机制,两个进程可以通过管道一个在管道一端向管道发送其输出,给另一进程可以在管道的另一端从管道得到
·
一、实验时间
2021年4月22日,星期四,第8周
二、实验内容
通过Linux 系统中管道通信机制,加深对于进程通信概念的理解,观察和体验并发进程间的通信和协作的效果 ,练习利用无名管道进行进程通信的编程和调试技术。
管道pipe是进程间通信最基本的一种机制,两个进程可以通过管道一个在管道一端向管道发送其输出,给另一进程可以在管道的另一端从管道得到其输入。管道以半双工方式工作,即它的数据流是单方向的。因此使用一个管道一般的规则是读管道数据的进程关闭管道写入端,而写管道进程关闭其读出端。
关键:利用pipe系统调用
三、示例实验
这个是实验指导书上的示例实验,关键要理解以下几点
- pipe系统调用的使用和声明
- 如何使用read方法和write方法读取和向发送另一个进程发送消息
- 注意close方法的使用,在发送消息或读取消息的时候管道的另一个端口需要关闭
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int pid; //进程号
int pipe1[2]; //存放第一个无名管道标号
int pipe2[2]; //存放第二个无名管道标号
int x; // 存放要传递的整数
//使用pipe()系统调用建立两个无名管道。建立不成功程序退出,执行终止
if(pipe(pipe1) < 0)
{
perror("pipe not create");
exit(EXIT_FAILURE);
}
if(pipe(pipe2) < 0)
{
perror("pipe not create");
exit(EXIT_FAILURE);
}
//使用fork()系统调用建立子进程,建立不成功程序退出,执行终止
if((pid=fork()) <0)
{
perror("process not create");
exit(EXIT_FAILURE);
}
//子进程号等于0 表示子进程在执行
else if(pid == 0)
{
//子进程负责从管道1的0端读,管道2的1端写
//所以关掉管道1的1端和管道2的0端。
close(pipe1[1]);
close(pipe2[0]);
//每次循环从管道1 的0 端读一个整数放入变量X 中,
//并对X 加1后写入管道2的1端,直到X大于10
do
{
read(pipe1[0],&x,sizeof(int));
printf("child %d read: %d\n",getpid(),x++);
write(pipe2[1],&x,sizeof(int));
}while( x<=9 );
//读写完成后,关闭管道
close(pipe1[0]);
close(pipe2[1]);
//子进程执行结束
exit(EXIT_SUCCESS);
}
//子进程号大于0 表示父进程在执行
else
{
//父进程负责从管道2的0端读,管道1的1端写,
//所以关掉管道1 的0 端和管道2 的1端。
close(pipe1[0]);
close(pipe2[1]);
x=1;
//每次循环向管道1 的1 端写入变量X 的值,并从
//管道2的0 端读一整数写入X 再对X加1,直到X 大于10
do
{
write(pipe1[1],&x,sizeof(int));
read(pipe2[0],&x,sizeof(int));
printf("parent %d read: %d\n",getpid(),x++);
}while(x<=9);
//读写完成后,关闭管道
close(pipe1[1]);
close(pipe2[0]);
}
//父进程执行结束
return EXIT_SUCCESS;
}
输出结果
在做本次实验之前最好理解清楚这个示例实验,里面具体的方法要求掌握
四、本次实验
实验内容
在这次实验的过程中我遇到了几个比较坑的地方,困扰了不少时间
- 这次实验中遇到了父进程创建两个子进程的问题,一开始的时候我没有调控好,在创建进程的时候遇到了很多问题,比如父进程已经执行完了,第二个子进程还在执行,后来在参考了别人的代码之后发现在判断if(pid == 0),else的时候要注意,两个进程不能并列判断
- 关于read方法和write的注意事项:起初我采用从管道的0端写,1端读,结果读出来的结果是随机数,很奇怪。后来我改成了从0端读,1端读,问题就顺利解决了
以下是这次实验的代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
//f(x)
int fx(int x)
{
if(x <= 0)
{
printf("the number you input is wrong!");
return 0;
}
else if(x == 1)
{
return 1;
}
else if(x > 1)
{
return fx(x-1) * x;
}
}
//f(y)
int fy(int y)
{
if(y <= 0)
{
printf("the number you input is wrong!");
return 0;
}
else if(y == 1 || y == 2)
{
return 1;
}
else if(y > 2)
{
return fy(y-1) + fy(y-2);
}
}
//f(x,y)
int fxy(int fx, int fy)
{
return fx + fy;
}
int main()
{
/*
建立三个进程,一个进程负责计算f(x)的值,一个负责计算f(y)的值,另一个负责计算f(x,y)的值
f(x),f(y)的值通过管道传输
*/
//建立两个管道
int pipe1[2];
int pipe2[2];
//两个子进程的进程号
int pid1;
int pid2;
//数值x和y
int x;
int y;
//从键盘输入x和y
printf("please input number x: ");
scanf("%d",&x);
printf("\n");
printf("please input number y: ");
scanf("%d",&y);
printf("\n");
//保存f(x)和f(y)的变量
int temp1,temp2;
//使用pipe()系统调用建立两个无名管道。建立不成功程序退出,执行终止
if(pipe(pipe1) < 0)
{
perror("pipe not create");
exit(EXIT_FAILURE);
}
if(pipe(pipe2) < 0)
{
perror("pipe not create");
exit(EXIT_FAILURE);
}
pid1 = fork();
//使用fork()系统调用建立子进程,建立不成功程序退出,执行终止
if(pid1 <0)
{
perror("process not create");
exit(EXIT_FAILURE);
}
//第一个子进程,pipe1[1]用来写
if(pid1 == 0)
{
//关掉pipe1[0]端
close(pipe1[0]);
//计算f(x)
temp1 = fx(x);
printf("pid1 f(x) = %d\n",temp1);
//发送消息
write(pipe1[1],&temp1,sizeof(int));
//发送完成后关闭管道
close(pipe1[1]);
}
else
{
close(pipe1[1]);
//读从管道1获得的数值
read(pipe1[0],&temp1,sizeof(int));
close(pipe1[0]);
pid2 = fork();
//使用fork()系统调用建立子进程,建立不成功程序退出,执行终止
if(pid2 <0)
{
perror("process not create");
exit(EXIT_FAILURE);
}
//第二个子进程,pipe2[1]用来写
if(pid2 == 0)
{
//关掉pipe2[0]端
close(pipe2[0]);
//计算f(y)
temp2 = fy(y);
printf("pid2 f(y) = %d\n",temp2);
//发送消息
write(pipe2[1],&temp2,sizeof(int));
close(pipe2[1]);
}
//父进程
else
{
wait(NULL);
close(pipe2[1]);
//接受第二个子进程从管道里发来的信息
read(pipe2[0],&temp2,sizeof(int));
int result = fxy(temp1,temp2);
printf("f(x) = %d\n",temp1);
printf("f(y) = %d\n",temp2);
printf("f(x,y) = %d\n",result);
//读完成后关闭管道
close(pipe2[1]);
//父进程执行结束
return EXIT_SUCCESS;
}
}
}
输入x=1,y=2的输出结果
输入x=5,y=5的输出结果
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献5条内容
所有评论(0)