操作系统实验进程通信
进程间通信

《操作系统》实验报告年级、专业、班级 姓名进程间通信实验题目实验时间 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;为0memset(buf, 0, sizeof(buf));//clear bufif(pipe(pipefd) < 0) {perror("pipe");exit(0);}pid = fork();if(pid == 0) { //child process 1close(pipefd[0]);//close read fdchar *msg="Hello,I am a Pipe user.";write(pipefd[1], msg, 50);}else if(pid > 0) {pid = fork();if(pid == 0) { //child process 2close(pipefd[1]);//close write fdread(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是队列idint 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() ;子进程p1if ( 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_STAT, &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 ;}四、实验结果及分析和(或)源程序调试过程(包含程序使用方法、程序运行截图),实验过程中遇到的问题分析与心得体会。
《Linux操作系统设计实践》实验二:进程通信

《Linux操作系统设计实践》实验二:进程通信实验目的:进一步了解和熟悉 Linux 支持的多种 IPC 机制,包括信号,管道,消息队列,信号量,共享内存。
实验环境: redhat实验内容:(1)进程间命名管道通信机制的使用:使用命名管道机制编写程序实现两个进程间的发送接收信息。
(2)进程间消息队列通信机制的使用:使用消息队列机制自行编制有一定长度的消息(1k 左右)的发送和接收程序。
(3)进程间共享存储区通信机制的使用:使用共享内存机制编制一个与上述(2)功能相同的程序。
并比较分析与其运行的快慢。
实验代码验证:(1).使用命名管道机制编写程序实现两个进程间的发送接收信息。
#include <stdio.h>#include <stdlib.h>#define FIFO_FILE "MYFIFO"int main(int argc, char *argv[]){FILE *fp;int i;if (argc<=1){printf("usage: %s <pathname>\n",argv[0]); exit(1);}if ((fp = fopen(FIFO_FILE, "w")) == NULL) {printf("open fifo failed. \n");exit(1);}for (i = 1; i < argc; i++){if (fputs(argv[i],fp) == EOF){printf("write fifo error. \n");exit(1);}if (fputs(" ",fp) == EOF){printf("write fifo error. \n"); exit(1);}}fclose(fp);return 0;}#include <stdio.h>#include <stdlib.h>#include <sys/stat.h>#include <unistd.h>#include <linux/stat.h>#define FIFO_FILE "MYFIFO"int main(){FILE *fp;char readbuf[80];if ((fp = fopen(FIFO_FILE, "r")) == NULL) {umask(0);mknod(FIFO_FILE, S_IFIFO | 0666, 0);}else{fclose(fp);}while (1){if ((fp = fopen(FIFO_FILE, "r")) == NULL) {printf("open fifo failed. \n");exit(1);}if (fgets(readbuf, 80, fp) != NULL){printf("Received string :%s \n", readbuf); fclose(fp);}else{if (ferror(fp)){printf("read fifo failed.\n");exit(1);}}}return 0;}实验结果:Server.c将client.c写入的字符输出。
操作系统实验报告(进程的管道及消息通信)

printf("\n Ihave wrote:%s",string); write(fd,string,45); string[0]+=1; } else { read(fd,buf,256); printf("\n The context by I have read is :!%s",buf); buf[0]='\0'; } } close(fd); } 运行结果:
char parent[]="A message to pipe'communication.\n";
main() {
int pid,chan1[2]; char buf[100]; pipe(chan1); pid=fork(); if(pid<0) {
printf("to create child error\n"); exit(1); } if(pid>0) { close(chan1[0]); printf("parent process sends a message to child.\n"); write(chan1[1],parent,sizeof(parent)); close(chan1[1]); printf("parent process waits the child to terminate\n"); wait(0); printf("parent process terminate\n"); } else { close(chan1[1]); read(chan1[0],buf,100); printf("The message read by child process from parent is :%s.\n",buf); close(chan1[0]); printf("child process terminates\n"); } } 运行结果:
操作系统进程通信报告

实验四:进程同步实验一、实验任务:1、熟悉操作系统进程通信原理2、设计程序,实现共享内存、管道通信、消息通信二、实验原理:1、进程间通信的几种方法简介(1)消息队列:消息队列是消息的链接表,包括Posix消息队列systemV消息队列。
有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。
(2)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。
是针对其他通信机制运行效率较低而设计的。
往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
(3)无名管道(Pipe)及有名管道(named pipe):有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;无名管道可用于有亲缘关系的进程之间彼此的通信,进行通信时候必须有一定的机制保证对管道写和读的互斥:即在读是要关闭写的端口,而在写的时候也要保证读的一端是关闭的。
2、进程通信函数(1)消息队列有关系统调用函数a.创建消息队列使用msgget()函数:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>int msgget(key_t key, int flag) ;该函数成功调用返回消息队列标识符。
其中的key是关键字,可以由ftok()函数得到:key=ftok(“.”,’a’);其中”.”可以是任何目录,’a’是任意字符,即所有群组标识。
flag是标识,IPC_CREAT位表示创建,一般由服务器程序创建消息队列时使用。
如果是客户程序,必须打开现存的消息队列,必须不使用IPC_CREAT。
发送和接收的消息都必须使用一个类似msgbuf的结构表示,msgbuf结构定义如下:struct msgbuf{long mtype;char mtext[1];}上面的定义,消息内容只有一个字节,是不实用的,一般我们需要重新定义一个结构:struct amsgbuf{long mtype;char mtext[200];}其中的mtype都是消息类型。
操作系统实验报告进程通信管理资料

漳州师范学院
实验报告
班级 13网络1班学号1308990337 姓名成绩
理解分析:1.先创建父进程,由父进程分别产生子进程1和子进程
p2,parent。
2.给父进程中断信号,父进程开始终止子进程,signal(SIGINT, SIG_IGN);语句,相当于使子进程忽略键入信号,不会将子进程终止,程序可以正常运行。
于是输出child process by parent!和child process 2 is killed by parent!
理解分析:在该管道通信中,有时是子进程p1,p2往管道中传送数据完后父进程再从管道中读取数据,有时是子进程p1往管道中传送数据后父进程从管道中读取数据,然后子进程p2再往管道中传送数据,父进程再从管道中读取数据。
1)管道通信的概念是什么
管道通信即发送进程以字符流形式将大量数据送入管道,接收进程可从管道接收数据,二者利用管道进行通信。
2)同步和互斥的概念是什么,在程序中如何实现的
注:如果填写内容超出表格,自行添加附页。
进程通信的实验报告

一、实验目的1. 理解进程通信的概念和作用。
2. 掌握进程通信的常用方法,包括管道、消息队列、信号量等。
3. 通过编程实践,加深对进程通信机制的理解和应用。
二、实验环境操作系统:Linux开发环境:gcc三、实验内容1. 管道通信2. 消息队列通信3. 信号量通信四、实验步骤及分析1. 管道通信(1)实验步骤1)创建一个父进程和一个子进程;2)在父进程中创建一个管道,并将管道的读端和写端分别赋给父进程和子进程;3)在父进程中,通过管道的写端发送数据给子进程;4)在子进程中,通过管道的读端接收父进程发送的数据;5)关闭管道的读端和写端;6)结束进程。
(2)实验分析通过管道通信,实现了父进程和子进程之间的数据传递。
管道是半双工通信,数据只能单向流动。
在本实验中,父进程向子进程发送数据,子进程接收数据。
2. 消息队列通信(1)实验步骤1)创建一个消息队列;2)在父进程中,向消息队列中发送消息;3)在子进程中,从消息队列中接收消息;4)删除消息队列;5)结束进程。
(2)实验分析消息队列是一种进程间通信机制,允许不同进程之间传递消息。
消息队列的创建、发送、接收和删除等操作都是通过系统调用实现的。
在本实验中,父进程向消息队列发送消息,子进程从消息队列接收消息,实现了进程间的消息传递。
3. 信号量通信(1)实验步骤1)创建一个信号量;2)在父进程中,对信号量执行P操作,请求资源;3)在子进程中,对信号量执行V操作,释放资源;4)结束进程。
(2)实验分析信号量是一种用于实现进程同步的机制。
在进程通信中,信号量可以用来协调多个进程对共享资源的访问。
在本实验中,父进程和子进程通过信号量实现了对共享资源的同步访问。
五、实验结果1. 管道通信实验结果:父进程成功向子进程发送数据,子进程成功接收数据。
2. 消息队列通信实验结果:父进程成功向消息队列发送消息,子进程成功从消息队列接收消息。
3. 信号量通信实验结果:父进程成功获取资源,子进程成功释放资源。
进程通讯管理实验报告(3篇)

第1篇一、实验目的1. 理解进程通信的概念和原理;2. 掌握进程通信的常用机制和方法;3. 能够使用进程通信机制实现进程间的数据交换和同步;4. 增强对操作系统进程管理模块的理解。
二、实验环境1. 操作系统:Linux2. 编程语言:C3. 开发环境:GCC三、实验内容1. 进程间通信的管道机制2. 进程间通信的信号量机制3. 进程间通信的共享内存机制4. 进程间通信的消息队列机制四、实验步骤1. 管道机制(1)创建管道:使用pipe()函数创建管道,将管道文件描述符存储在两个变量中,分别用于读和写。
(2)创建进程:使用fork()函数创建子进程,实现父子进程间的通信。
(3)管道读写:在父进程中,使用read()函数读取子进程写入的数据;在子进程中,使用write()函数将数据写入管道。
(4)关闭管道:在管道读写结束后,关闭对应的管道文件描述符。
2. 信号量机制(1)创建信号量:使用sem_open()函数创建信号量,并初始化为1。
(2)获取信号量:使用sem_wait()函数获取信号量,实现进程同步。
(3)释放信号量:使用sem_post()函数释放信号量,实现进程同步。
(4)关闭信号量:使用sem_close()函数关闭信号量。
3. 共享内存机制(1)创建共享内存:使用mmap()函数创建共享内存区域,并初始化数据。
(2)映射共享内存:在父进程和子进程中,使用mmap()函数映射共享内存区域。
(3)读写共享内存:在父进程和子进程中,通过指针访问共享内存区域,实现数据交换。
(4)解除映射:在管道读写结束后,使用munmap()函数解除映射。
4. 消息队列机制(1)创建消息队列:使用msgget()函数创建消息队列,并初始化消息队列属性。
(2)发送消息:使用msgsnd()函数向消息队列发送消息。
(3)接收消息:使用msgrcv()函数从消息队列接收消息。
(4)删除消息队列:使用msgctl()函数删除消息队列。
实验一 进程通信操作系统实验报告

验
内
容
2.用pipe()创建一个管道,然后用fork()创建两个生产进程和两个消费进程,它们之间能过pipe()传递信息。
实
验
结果
遇到问题及解决方法
int i,pid,status;
for(i=0;i<4;i++) pid=wait(*status); i,pid,status;
实
验
结果
遇到问题及解决方法
retval=clone((void*)producer,&(stack[4095]),clone_flag, (void*&arg);此语句void*后缺少),正确语句应为:
retval=clone((void*)producer,&(stack[4095]),clone_flag, (void*)&arg);
for(i=0;i<4;i++) pid=wait(&status);
if(id==1) stcopy(w_buf,"ccc\0");
else strcpy(w_buf,"ddd\0");
此语句中stcopy词语写错,应改为strcpy,即
if(id==1) strcpy(w_buf,"ccc\0");
学年第学期
操作系统课程
实验报告
学院:
专业:
班级:
姓名:
学号:
任课教师:
实验日期:2017年4月11日
实验题目
实验一进程通信
实验地点
实验目的
1.理解Linux系统的进程通信机构(IPC)允许在任意进程间大批量地交换数据的过程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告课程名称:操作系统实验名称:进程通信实验类型:实验室名称:计算机应用实验室实验报告撰写要求一、实验前用预习报告纸撰写预习报告,预习报告包括以下内容1.实验目的2.实验用仪器设备、器材或软件环境3.实验原理、方案设计、程序框图、预编程序等4.实验过程中需要记录的实验数据表格二、实验过程中,要认真观察,仔细记录三、完成实验后用实验报告纸撰写实验报告,包括以下内容1.仪器设备型号及编号2.实验器材或软件环境3.实验步骤、程序调试方法4.实验数据处理及结果分析5.实验中存在的问题6.体会及思考题四、报告撰写时,要求格式规范、书写整齐预习报告□报告成绩:指导教师审核(签名):年月日实验二进程通信一、实验目的1.加深对各种进程通信基本工作原理的理解。
2.理解和掌握Linux系统中进程通信API的应用方法。
3.进一步认识进程软中断通信、管道通信和消息队列通信的实质。
4.分析、设计进程软中断通信的实现方法。
5.分析、设计进程的管道通信,实现父子进程的单机通信机制。
6.分析、设计进程的消息队列通信,实现客户机/服务器通信机制。
二、实验类型设计性实验。
三、实验预备知识1.阅读Linux进程通信技术(软中断、管道和消息队列)的使用方法。
2.阅读Linux系统中单机和多机通信技术,掌握各种通信技术API的基本应用方法。
四、实验内容1.进程的软中断通信【举例1】编制一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按任意字母键和Enter键),当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:child process 1 is killed by parent!child process 2 is killed by parent!父进程等待两个子进程终止后,输出以下信息后终止:parent process is killed!【程序】#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <signal.h>void waiting(),stop();int wait_mark;main(){int p1,p2;while((p1=fork())= =-1); /*创建进程p1*/if(p1>0){while((p2=fork())= =-1); /*创建进程p2*/if(p2>0){Printf(“parent run!\n”);Printf(“p1=%d\n”,p1);Printf(“p2=%d\n”,p2);wait_mark=1;getchar();kill(p1,16); /*向p1发软中断信号16*/kill(p2,17); /*向p2发软中断信号17*/sleep(5); /*父进程睡眠5秒*/wait(0); /*等待子进程结束,同步*/wait(0); /*等待另一子进程结束,同步*/lockf(stdout,1,0); /*标准输出加锁*/printf(“parent process is killed!\n”);lockf(stdout,0,0); /*标准输出解锁*/exit(0); /*父进程终止*/}else{printf(“p2 run!\n”);wait_mark=1;signal(17,stop); /*接收父进程发来的软中断信号17,并转stop*/waiting();lockf(stdout,1,0); /*标准输出加锁*/printf(“child process 2 is killed by parent!\n”);lockf(stdout,0,0); /*标准输出解锁*/exit(0); /*子进程p2终止*/}} else {printf(“p1 run!\n”);wait_mark=1;signal(16,stop); /*接收父进程发来的软中断信号16,并转stop*/waiting();lockf(stdout,1,0); /*标准输出加锁*/printf(“child process 1 is killed by parent!\n”);lockf(stdout,0,0); /*标准输出解锁*/exit(0); /*子进程p1终止*/}}void waiting(){printf(“waiting begin!\n”);while(wait_mark!=0);printf(“waiting end!\n”);}void stop(){wait_mark=0;printf(“signal stop!”);}【执行结果】p1,p2和parent进程依次执行后,得到P1,P2的值为随机连续的值,按回车键输入中断信号后,通过signal()接收后,父进程向子进程发送信号,子进程p1,p2.parent进程依次结束,并打印相应的输出语句。
【分析原因】先创建父进程,由父进程分别产生子进程p1和子进程p2,依次输出p1,p2,parent。
随后用signal()接收给父进程中断信号,父进程通过kill()发信息给子进程,终止子进程,运行stop函数wait_mark=0;跳出waiting函数,输出parent process is killed!【举例2】在上面任务1中,增加语句signal(SIGINT,SIG_IGN)和语句signal(SIGQUIT,SIG_IGN),观察执行结果,并分析原因。
这里signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN)分别为忽略“Ctrl+c”键信号以及忽略中断信号。
【程序】#include <sys/types.h>#include <unistd.h>#include <stdio.h>#include <signal.h>int pid1,pid2;int endflag=0,pf1=0,pf2=0;void intdelete(){ kill(pid1,16);kill(pid2,17);endflag=1;}void int1(){printf(“child process 1 is killed by parent!”);exit(0);}void int2(){printf(“child process 2 is killed by parent!”);exit(0);}main(){int exitpid;signal(SIGINT,SIG_IGN);signal(SIGQUIT,SIG_IGN);while((pid1=fork())= =-1);if(pid1= =0){printf(“process 1 run!\n”);signal(SIGUSR1,int1);signal(16, SIG_IGN);pause();exit(0);}else{while((pid2=fork())= =-1);if(pid2= =0){printf(“process 2 run!\n”);signal(SIGUSR2,int2);signal(17, SIG_IGN);pause();exit(0);}else{printf(“parent run!\n”);signal(SIGINT,intdelete);waitpid(-1,&exitpid,0);printf(“parent process is killed!\n”);exit(0);}}}【执行结果】Process 1 run! Process 2 run! Parent run! 按回车键后,进程也无法结束。
【分析原因】由于忽略了终端与退出的信号,程序会一直保持阻塞状态而无法退出。
2.进程的管道通信【举例】编制一段程序,实现进程的管道通信。
使用系统调用pipe()建立一条管道线。
两个子进程p1和p2分别向管道各写一句话:child 1 is sending a message!child 2 is sending a message!而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。
【程序】#include <unistd.h>#include <stdio.h>#include <signal.h>int pid1,pid2;main(){int fd[3];char outpipe[100],inpipe[100];pipe(fd);while((pid1=fork())= =-1);if(pid1= =0){printf(“p1 run!\n”);lockf(fd[1],1,0);sprintf(outpipe,”child 1 process is sending a message!”);write(fd[1],outpipe,50);sleep(1);lockf(fd[1],0,0);exit(0);}else{while((pid2=fork())= =-1);if(pid2= =0){printf(“p2 run!\n”);lockf(fd[1],1,0);sprintf(outpipe,”child 2 process is sending a message!”);write(fd[1],outpipe,50);sleep(1);lockf(fd[1],0,0);exit(0);}else{printf(“parent run!\n”);wait(0);read(fd[0],inpipe,50);printf(“%s\n”,inpipe);wait(0);read(fd[0],inpipe,50);printf(“%s\n”,inpipe);exit(0);}}}【执行结果】进程p1,p2,parent依次执行,随后打印,child 1 process is sending a message! child 2 process is sending a message! 还出现进程p1执行,parent执行p2再执行的情况,随后打印的结果相同。
【分析原因】在该管道通信中,有时是子进程p1,p2往管道中传送数据完后父进程再从管道中读取数据,有时是子进程p1往管道中传送数据后父进程从管道中读取数据,然后子进程p2再往管道中传送数据,父进程再从管道中读取数据。
3.进程的消息队列通信实验要求:(1)实现客户机与服务器之间的通信程序。