进程间通信

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
四、实验结果及分析和(或)源程序调试过程(包含程序使 用方法、程序运行截图),实验过程中遇到的问题分析与心 得体会。(实验报告中最重要的部分,应尽量详细,重点描 述自己遇到的问题以及解决方法)
1. 实验结果 (1)管道通信,子进程p1打开给定文件a.txt,并向文件中写入字符 串”Hello,I am a Pipe user.”,写完关闭文件,然后向管道写入一条消 息“ok",子进程p2通过管道读取消息,如果消息是“ok”,则打开文件, 读取文件内容,并将其输出到屏幕上,关闭文件,实验结果如下图:
if ( shmid < 0 ) { perror("get shm ipc_id error") ; return -1 ;
} pid = fork() ; if ( pid == 0 ){ //子进程p1
printf("I'm child1 process,my pid is %d.\n",getpid()); sem_p(sem_id); // P操作 shmaddr = (char *)shmat( shmid, NULL, 0 ) ;//链接到存储区 if ( (int)shmaddr == -1 ){
} printf("%s", shmaddr) ; //打印数据到屏幕 sem_v(sem_id); // V操作 shmdt( shmaddr) ;//断开链接 } else{ perror("fork error.") ; shmctl(shmid, IPC_RMID, NULL) ; } shmctl(shmid, IPC_RMID, NULL) ;//删除该存储区 return 0 ; }
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 ;
1 3 4 5 6
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) {
(2)消息队列,子进程p1打开给定文件a.txt,并向文件中写入字符 串”Hello,I am a Pipe user.”,写完关闭文件,然后向消息队列写入一条 消息“1",子进程p2从消息队列读取消息,如果收到消息,则打开文件, 读取文件内容,并将其输出道屏幕上,关闭文件,实验结果如下图:
(3)共享存储,子进程p1链接到该共享存储区,然后向存储区写入 数据,写完断开链接,子进程p2链接到该共享存储区,从存储区读数 据,然后断开链接,实验结果如下图:
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_NOWAIT)) != 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}; int msg_len = msgrcv(msqid, &msg, sizeof(msg.mtext), 0, IPC_NOWAIT); //接收消息函数 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_PRIVATE, SIZE, IPC_CREAT|0600 ) ;//创建共享存 储区
perror("shmat addr error") ; return -1 ; } strcpy( shmaddr, "Hi,This is share memory!\n") ;//向存储区写数据 shmdt( shmaddr ) ;//断开链接 sem_v(sem_id); // V操作 } else if ( pid > 0) {//父进程 printf("I'm father process,my pid is %d.\n",getpid()); pid = fork(); sleep(1); if(pid==0){//子进程2创建 printf("I'm child2 process,my pid is %d.\n",getpid()); sem_p(sem_id); // P操作 flag = shmctl( shmid, IPC_STAT, &buf) ;//读取存储区状态到buf中 if ( flag == -1 ) {
2. 实验分析及调试过程 此次实验使用了管道通信和消息队列通信得方法,让我们了解了管道 通信的特点,掌握了管道通信的使用方法和了解了消息队列通信机制 及原理,掌握了消息队列相关系统调用的使用方法及功能,另外,我 们也了解了Linux系统共享存储区的原理及使用方法。在此次实验中, 我们也遇到了许多问题,首先,对文件的读写操作没有掌握好,通过 查阅资料了解文件的读写操作,完成了第一个实验内容;在写第二个 程序的时候,一直出现打开队列文件错误的问题,最后经过不断调试 和查阅资料,修改了路径,解决了这个问题。
《操作系统》实验报告
年级、专业、班级
姓名
实验题目
进程间通信
实验时间
2014.11.21
实验地点
A主0410
Байду номын сангаас
实验成绩
□验证性 □设计
实验性质
性 □综合性
教师评价:
□算法/实验过程正确; □源程序/实验内容提交 □程序结构/实
验步骤合理;
□实验结果正确;
□语法、语义正确;
□报告规范;
其他:
评价教师签名:
一、实验目的
1. 了解管道通信的特点,掌握管道通信的使用方法。 2. 了解消息队列通信机制及原理,掌握消息队列相关系统调用的使用 方法及功能。 3. 了解Linux系统共享存储区的原理及使用方法。
二、实验项目内容
1. 管道通信 (1)父进程创建管道和两个子进程p1和p2。 (2)子进程p1打开给定文件(如果没有,则创建文件),并向文件 中写数据,写完关闭文件,然后向管道写入一条消息“ok",目的是通 知进程p2可以读取文件内容了。 (3)子进程p2通过管道读取消息,如果消息是“ok”,则打开文件,读 取文件内容,并将其输出到屏幕上,关闭文件.
三、实验过程或算法
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; memset(buf, 0, sizeof(buf));//clear buf为0 if(pipe(pipefd) < 0) {
2. 消息队列 (1)父进程创建消息队列和两个子进程p1和p2。 (2)子进程p1打开给定文件(如果没有,则创建文件),并向文件 中写数据,写完关闭文件,然后向消息队列写入一条消息“1",目的是通 知进程p2可以读取文件内容了。
(3)子进程p2从消息队列读取消息,如果收到消息,则打开文件,读 取文件内容,并将其输出道屏幕上,关闭文件。 3. 共享存储 (1)由父进程建立一块共享存储区,并创建两个子进程p1,p2,父进程负 责查询存储区状态,以及删除该存储区。 (2)子进程p1链接到该共享存储区,然后向存储区写入数据,写完 断开链接。 (3)子进程p2链接到该共享存储区,从存储区读数据,然后断开链 接。 注意:为了便于各进程对存储区访问的同步,这里使用信号量方法。
相关文档
最新文档