进程间通信

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《操作系统》实验报告
年级、专业、班级 姓名
进程间通信
实验题目
实验时间 2014.11.21 实验地点 A主0410
实验成绩 实验性质 □验证性 □设计性 □综合性 教师评价:
□算法/实验过程正确; □源程序/实验内容提交 □程序结构/实验步骤合理;
□实验结果正确; □语法、语义正确; □报告规范;
其他:
评价教师签名:
一、实验目的
1. 了解管道通信的特点,掌握管道通信的使用方法。

2. 了解消息队列通信机制及原理,掌握消息队列相关系统调用的使用方法及功能。

3. 了解Linux系统共享存储区的原理及使用方法。

二、实验项目内容
1. 管道通信
(1)父进程创建管道和
两个子进程p1和p2。

(2)子进程p1打开给定
文件(如果没有,则创建文
件),并向文件中写数据,
写完关闭文件,然后向管道
写入一条消息“ok",目的
是通知进程p2可以读取文
件内容了。

(3)子进程p2通过管道
读取消息,如果消息是“ok”,
则打开文件,读取文件内
容,并将其输出到屏幕上,
关闭文件.
2. 消息队列
(1)父进程创建消息队列
和两个子进程p1和p2。

(2)子进程p1打开给定文
件(如果没有,则创建文件),
并向文件中写数据,写完关闭
文件,然后向消息队列写入一
条消息“1",目的是通知进程
p2可以读取文件内容了。

(3)子进程p2从消息队列
读取消息,如果收到消息,则
打开文件,读取文件内容,并
将其输出道屏幕上,关闭文
件。

3. 共享存储
(1)由父进程建立一块共
享存储区,并创建两个子进程
p1,p2,父进程负责查询存储区
状态,以及删除该存储区。

(2)子进程p1链接到该共
享存储区,然后向存储区写入
数据,写完断开链接。

(3)子进程p2链接到该共
享存储区,从存储区读数据,
然后断开链接。

注意:为了便于各进程对存储区访问的同步,这里使用信号量方法。

三、实验过程或算法
1. 管道通信
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main() {
int pipefd[2];
pid_t pid;
char buf[100];
int n;
为0
memset(buf, 0, sizeof(buf));//clear buf
if(pipe(pipefd) < 0) {
perror("pipe");
exit(0);
}
pid = fork();
if(pid == 0) { //child process 1
close(pipefd[0]);//close read fd
char *msg="Hello,I am a Pipe user.";
write(pipefd[1], msg, 50);
}
else if(pid > 0) {
pid = fork();
if(pid == 0) { //child process 2
close(pipefd[1]);//close write fd
read(pipefd[0], buf, sizeof(buf));
fprintf(stdout, "read from pipe is:%s\n", buf);
}
else if(pid > 0) exit(0);
}
}
2.消息队列
//发送消息,msqid是队列id,msg是要发送的消息
void sendmsg(int msqid,mymesg msg){
printf("msqid:%d,msg:%s\n",msqid,msg.mtext);
if((msgsnd(msqid, &msg, sizeof(msg.mtext), IPC_NOW
AIT)) != 0){
//消息发送函数
printf("pid_1:send msg error!\n");
}
else{
printf("pid_1:send msg: %s succeed!\n", msg.mtext);
}
}
//接收消息,msqid是队列id
int rcvmsg(int msqid){
mymesg msg={0};
AIT);
int msg_len = msgrcv(msqid, &msg, sizeof(msg.mtext), 0, IPC_NOW //接收消息函数
if(msg_len < 0){
printf("pid_2:receive msg error!\n");
return 0;
}
printf("pid_2:recv msg: %s\n", msg.mtext);
return 1;
}
3.共享存储
创建共享存储区 shmid = shmget(IPC_PRIV A TE, SIZE, IPC_CREAT|0600 ) ;//
{
if ( shmid < 0 )
perror("get shm ipc_id error") ;
return -1 ;
}
pid = fork() ;
子进程p1
if ( pid == 0 ){ //
printf("I'm child1 process,my pid is %d.\n",getpid());
P操作
sem_p(sem_id); //
链接到存储区 shmaddr = (char *)shmat( shmid, NULL, 0 ) ;//
if ( (int)shmaddr == -1 ){
perror("shmat addr error") ;
return -1 ;
}
向存储区写数据
strcpy( shmaddr, "Hi,This is share memory!\n") ;//
shmdt( shmaddr ) ;//
断开链接
V操作
sem_v(sem_id); //
父进程
} else if ( pid > 0) {//
printf("I'm father process,my pid is %d.\n",getpid());
pid = fork();
sleep(1);
子进程2创建
if(pid==0){//
printf("I'm child2 process,my pid is %d.\n",getpid());
P操作
sem_p(sem_id); //
读取存储区状态到buf中
flag = shmctl( shmid, IPC_STA
T, &buf) ;//
{
if ( flag == -1 )
perror("shmctl shm error") ;
return -1 ;
}
printf("shm_segsz =%d bytes\n", buf.shm_segsz ) ;
printf("parent pid=%d, shm_cpid = %d \n", getppid(), buf.shm_cpid ) ;
printf("chlid pid=%d, shm_lpid = %d \n",pid, buf.shm_lpid ) ;
printf("shm_segsz =%d \n", buf.shm_perm.mode );
shmaddr = (char *) shmat(shmid, NULL, 0 ) ;
链接到存储区,读取其中数据
if ( (int)shmaddr == -1 ){//
perror("shmat addr error") ;
return -1 ;
}
//打印数据到屏幕
printf("%s", shmaddr) ;
V操作
sem_v(sem_id); //
断开链接
shmdt( shmaddr) ;//
}
else{
perror("fork error.") ;
shmctl(shmid, IPC_RMID, NULL) ;
}
删除该存储区
shmctl(shmid, IPC_RMID, NULL) ;//
return 0 ;
}
四、实验结果及分析和(或)源程序调试过程(包含程序使用方法、程
序运行截图),实验过程中遇到的问题分析与心得体会。

(实验报告中
最重要的部分,应尽量详细,重点描述自己遇到的问题以及解决方法)
1. 实验结果
(1)管道通信,子进程p1打开给定文件a.txt,并向文件中写入字符串”Hello,I am
a Pipe user.”
,写完关闭文件,然后向管道写入一条消息“ok",子进程p2通过管
道读取消息,如果消息是“ok”,则打开文件,读取文件内容,并将其输出到屏幕
上,关闭文件,实验结果如下图:
(2)消息队列,子进程p1打开给定文件a.txt,并向文件中写入字符串”Hello,I am ,写完关闭文件,然后向消息队列写入一条消息“1",子进程p2从消息
a Pipe user.”
队列读取消息,如果收到消息,则打开文件,读取文件内容,并将其输出道屏幕上,
关闭文件,实验结果如下图:
(3)共享存储,子进程p1链接到该共享存储区,然后向存储区写入数据,写
完断开链接,子进程p2链接到该共享存储区,从存储区读数据,然后断开链接,
实验结果如下图:
2.实验分析及调试过程
此次实验使用了管道通信和消息队列通信得方法,让我们了解了管道通信的特点,掌握了管道通信的使用方法和了解了消息队列通信机制及原理,掌握了消息队列相关系统调用的使用方法及功能,另外,我们也了解了Linux系统共享存储区的原理及使用方法。

在此次实验中,我们也遇到了许多问题,首先,对文件的读写操作没有掌握好,通过查阅资料了解文件的读写操作,完成了第一个实验内容;在写第二个程序的时候,一直出现打开队列文件错误的问题,最后经过不断调试和查阅资料,修改了路径,解决了这个问题。

相关文档
最新文档