实验二,进程通信,管道共享内存

合集下载

《Linux操作系统设计实践》实验二:进程通信

《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写入的字符输出。

进程实验-进程间通信(管道、消息、共享内存、软中断)

进程实验-进程间通信(管道、消息、共享内存、软中断)

进程实验3 Linux 进程间通信一、软中断信号的处理,实现同一用户的各进程之间的通信。

●相关的系统调用⏹kill(pid ,sig):发送信号⏹signal(sig, func):指定进程对信号sig的处理行为是调用函数func。

●程序清单#include <unistd.h>#include <stdio.h>#include <signal.h>void waiting();void stop();int wait_mark;main(){int p1,p2;while((p1=fork())==-1);if(p1>0){while((p2=fork())==-1);if(p2>0){ printf("parent\n");/*父进程在此完成某个操作、或接收到用户从键盘输入的特殊按键命令后发出下面的信号。

这里省略。

*/kill(p1,16);kill(p2,17);wait(0);wait(0);printf("parent process id killed! \n");exit(0);}else/* p2==0*/{printf("p2\n");wait_mark=1;signal(17,stop);waiting();printf("child process 2 is killed by parent! \n");exit(0);}}else/*p1==0*/{printf("p1\n");wait_mark=1;signal(16,stop);waiting();printf("child process 1 is kelled by parent! \n");exit(0);}}void waiting(){while(wait_mark!=0);}void stop(){wait_mark=0;}●输入并运行此程序,分析程序的运行结果。

操作系统实验报告(进程的管道及消息通信)

操作系统实验报告(进程的管道及消息通信)
if(argc==2) {
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)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析
实验代码:
#include<stdio.h>
main()
{ int x,fd[2];
char buf[30],s[30];
pipe(fd);
while ((x=fork())==-1);
if (x==0)
}
write(fe[1],s,30);
wait(0);
}
运行结果:
(3)阅读例2的程序,运行一次该程序,然后用ipcs命令查看系统中共享存储区的情况,再次执行该程序,再用ipcs命令查看系统中共享内存的情况,对两次的结果进行比较,并分析原因。最后用ipcrm命令删除自己建立的共享存储区。(有关ipcs和ipcrm介绍见后面一页)
addr=shmat(shmid,0,0);/*挂接,并得到共享区首地址*/
printf ("addr 0x%x\n",addr);
pint=(char *)addr;
for (i='a';i<='e';i++) *pint++=i;
pause();/*等待接收进程读*/
}
cleanup()
{
shmctl(shmid,IPC_RMID,0);
(2)每个同学登陆两个窗口,先在一个窗口中运行例3程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),然后在另一个窗口中运行例3程序2,观察程序的运行结果并分析。运行结束后可以用ctrl+c结束程序1的运行。
(3)编写程序:使用系统调用shmget(),shmat(),shmdt(),shmctl(),编制程序。要求在父进程中生成一个30字节长的私有共享内存段。接下来,设置一个指向共享内存段的字符指针,将一串大写字母写入到该指针指向的存贮区。调用fork()生成子进程,让子进程显示共享内存段中的内容。接着,将大写字母改成小写,子进程修改共享内存中的内容。之后,子进程将脱接共享内存段并退出。父进程在睡眠5秒后,在此显示共享内存段中的内容(此时已经是小写字母)。

操作系统原理进程通信共享内存

操作系统原理进程通信共享内存

操作系统原理进程通信共享内存操作系统中的进程通信和共享内存是两个相互关联的概念。

进程通信是指不同进程之间进行信息交换的机制,而共享内存则是实现进程通信的一种方法。

在本文中,我们将详细介绍进程通信和共享内存的原理和一些常用的实现方式。

一、进程通信的原理进程通信是操作系统中实现不同进程之间信息传递和协同工作的关键机制。

它可以分为两种基本形式:同步和异步。

1.同步通信:同步通信是指发送进程和接收进程在通信操作期间需要进行协调和同步。

在同步通信中,发送进程必须等待接收进程完成后才能继续执行。

2.异步通信:异步通信是指发送进程和接收进程在通信操作期间相互独立,不需要进行明确的协调和同步。

在异步通信中,发送进程可以在发送消息后立即继续执行其他任务,而不需要等待接收进程。

常见的进程通信机制包括管道、消息队列、信号量和套接字等。

下面将对其中的一种机制进行详细介绍。

1. 管道(Pipe):管道是一种特殊的文件,用于将一个进程的输出连接到另一个进程的输入。

管道提供了一种单向的、先进先出的数据传输方式。

在管道中,写操作和读操作是同步的,即写操作会一直阻塞直到有进程来读取数据。

很多操作系统提供了管道的实现方式,如在Unix/Linux中可以使用pipe(系统调用创建一个管道。

在创建管道后,相关进程可以通过文件描述符进行读写操作。

二、共享内存的原理共享内存是一种允许两个或多个进程之间共享地址空间的机制。

通过共享内存,进程可以直接读取和修改彼此的数据,从而实现高效的数据共享。

共享内存的实现包括以下步骤:1. 创建共享内存区域:操作系统提供了一些系统调用,如shmget(,用于创建共享内存区域。

创建共享内存区域时需要指定大小和一些其他的控制参数。

2. 连接到共享内存:创建共享内存区域后,进程可以使用shmat(系统调用将共享内存区域连接到自己的地址空间,从而可以直接读取和修改共享内存中的数据。

3.操作共享内存:连接到共享内存后,进程可以像操作普通内存一样对共享内存进行读写操作。

试验二进程通信Linux试验报告

试验二进程通信Linux试验报告

实验报告学号姓名成绩__________实验二进程通信【实验目的和要求】1、了解进程通信的概念及方法;2、了解信号量、管道;3、掌握信号量、管道和命名管道编程方法。

【实验内容】1、利用命名管道实现单机QQ聊天;2、撰写实验报告;【实验原理】1、信号量(semaphore)是为那些访问相同资源的进程以及同一进程不同线程之间提供的一个同步机制。

它不是用于传输数据,而只是简单地协调对共享资源的访问。

信号量包含一个计数器,表示某个资源正在被访问和访问的次数,用来控制多进程对共享数据的访问。

一旦成功拥有了一个信号量,对它所能做的操作只有两种:请求和释放。

当执行释放操作时,系统将该信号值减1(如果小于零,则设置为零);当执行请求操作时,系统将该信号值加1,如果加1后的值大于设定的最大值,那么系统将会挂起处理进程,直到信号值小于最大值为止。

Tuxedo 用信号量来确保在某一时刻只有一个进程对某一块共享内存进程访问。

信号量配置太低会导致Tuxedo系统应用程序无法启动。

2、管道分为两种:管道和命名管道。

管道是UNIX系统IPC的最古老形式,并且所有的UNIX系统都提供这种通信机制。

可以在有亲缘关系(父子进程或者是兄弟进程之间)进行通信,管道的数据只能单向流动,如果想双向流动,必须创建两个管道。

管道应用的一个重大缺陷就是没有名字,因此只能用于亲缘进程之间的通信。

后来以管道为基础提出命名管道(namedpipe,FIFO)的概念,该限制得到了克服。

FIFO不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。

这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。

值得注意的是,FIFO严格遵循先进先出(first in first out)规则,对管道及FIFO的读总是从开始处返回数据,对它们的写则是把数据添加到末尾。

进程通信的实验报告

进程通信的实验报告

一、实验目的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篇)

进程通讯管理实验报告(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()函数删除消息队列。

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

操作系统实验报告实验二:进程通信(一)——管道及共享内存一、实验目的•了解进程之中相互通信的方式•加深对管道通信的了解•了解共享内存通信的程序设计方法•了解和熟悉Linux支持的共享存储区机制二、实验内容和步骤任务一、(1)阅读以上父子进程利用管道进行通信的例子(例1),写出程序的运行结果并分析。

(2)编写程序:父进程利用管道将一字符串交给子进程处理。

子进程读字符串,将里面的字符反向后再交给父进程,父进程最后读取并打印反向的字符串任务二、1)阅读例2的程序,运行一次该程序,然后用ipcs命令查看系统中共享存储区的情况,再次执行该程序,再用ipcs命令查看系统中共享内存的情况,对两次的结果进行比较,并分析原因。

最后用ipcrm命令删除自己建立的共享存储区。

(有关ipcs和ipcrm介绍见后面一页)(2)每个同学登陆两个窗口,先在一个窗口中运行例3程序1(或者只登陆一个窗口,先在该窗口中以后台方式运行程序1),然后在另一个窗口中运行例3程序2,观察程序的运行结果并分析。

运行结束后可以用ctrl+c结束程序1的运行。

(3)编写程序:使用系统调用shmget(),shmat(),shmdt(),shmctl(),编制程序。

要求在父进程中生成一个30字节长的私有共享内存段。

接下来,设置一个指向共享内存段的字符指针,将一串大写字母写入到该指针指向的存贮区。

调用fork()生成子进程,让子进程共享内存段中的内容。

接着,将大写字母改成小写,子进显示程修改共享内存中的内容。

之后,子进程将脱接共享内存段并退出。

父进程在睡眠5秒后,在此显示共享内存段中的内容(此时已经是小写字母)。

三、代码及运行结果分析1.任务1(1)①代码:#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<sys/wait.h>#include<string.h>#include<stdlib.h>int main(){int x,fd[2];char buf[30],s[30];pipe(fd);while((x=fork())==-1);if(x==0){close(fd[0]);printf("Child Process!\n");strcpy(buf,"This is an example\n");write(fd[1],buf,30);exit(0);}else{close(fd[1]);printf("Parent Process!\n");read(fd[0],s,30);printf("%s\n",s);}}②截图:③结果和分析:创建一个管道,调用fork()函数产生两个进程,我的系统优先先执行父进程,比较疑惑,既然这样,管道中并没有数据是如何得出最后结果的,后来百度了一下解释说是因为管道本身是一种同步机制,并且printf执行的时间要比其他程序时间长得多,才会这样。

然后执行子程序,将数据写入管道,然后父程序打印出来2. 任务1(2)①代码:#include<stdio.h>#include<sys/types.h>#include<unistd.h>#include<sys/wait.h>#include<string.h>#include<stdlib.h>void fanzhuan(char *s){char *p=s+strlen(s)-1;char temp;while(s<p){temp=*p;*p--=*s;*s++=temp;}}int main(){int i,x,fd[2];char buf[20],s[20],m[20];strcpy(buf,"This is an example\n");pipe(fd);write(fd[1],buf,20);while((x=fork())==-1);if(x==0){printf("Child Process!\n");read(fd[0],s,20);//printf("%s\n",s);fanzhuan(s);write(fd[1],s,20);exit(0);}else{wait(NULL);close(fd[1]);printf("Parent Process!\n");read(fd[0],m,20);printf("%s\n",m);}}②截图:3. 任务2(1)①代码:#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#include<stdio.h>#include<stdlib.h>int main(){key_t key=105;int shmid_1,shmid_2;if((shmid_1=shmget(key,1000,0644|IPC_CREAT))==-1){ perror("shmget shmid_1");exit(1);}printf("First shared memory identifier is %d\n",shmid_1);if((shmid_2=shmget(IPC_PRIVATE,20,0644))==-1){ perror("shmget shmid_2");exit(2);}printf("Second shared memory identifier is %d\n",shmid_2);exit(0);}②截图:③结果和分析:两次运行结束后,第二个共享标识符不一样,然后在每一次的ipcs 查看共享存储区的时候,最后一行也是不一样的。

原因是分配了两次,然后第一次有key值,第二次是没有的。

4. 任务2(2)①代码:程序1:#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<unistd.h>#define SHMKEY 105#define K 1024int shmid;int main(){int i,*pint;char *addr;extern void* shmat();extern cleanup();for(i=0;i<20;i++)signal(i,cleanup);shmid=shmget(SHMKEY,16*K,0777|IPC_CREAT);addr=shmat(shmid,0,0);printf("addr 0x%x\n",addr);pint=(int *)addr;for(i=0;i<256;i++)*pint++=i;pause();}cleanup(){shmctl(shmid,IPC_RMID,0);exit(0);}程序2:#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#include<stdio.h>#include<stdlib.h>#include<signal.h>#include<unistd.h>#define SHMKEY 105#define K 1024int shmid;int main(){int i,*pint;char *addr;extern void *shmat();shmid=shmget(SHMKEY,8*K,0777);addr=shmat(shmid,0,0);pint=(int *)addr;for(i=0;i<256;i++)printf("%d\n",*pint++);}②截图:③结果和分析:程序(1)后台运行的时候,先创建一个共享内存段,然后挂接,得到共享区的地址,并且输出这个地址,然后pint的首地址就是共享区首地址,向共享区里面输入1,2,3,4,5.。

155。

程序(2)执行的时候首先先挂接到这个共享区,然后向从首地址开始遍历,输出其中的内容5. 任务2(3)①代码:#include<sys/types.h>#include<sys/ipc.h>#include<sys/shm.h>#include<stdlib.h>#include<unistd.h>#include<sys/wait.h>#include<string.h>#include<stdio.h>int main(){key_t key=105;int shmid,p1,i;char *addr,*pint,temp;shmid=shmget(key,30,0644|IPC_CREAT);addr=shmat(shmid,0,0);for(i=0;i<5;i++){*addr='A'+i;addr++;}while((p1=fork())==-1);if(p1==0){shmid=shmget(105,30,0644);printf("success\n");addr=shmat(shmid,0,0);for(i=0;i<5;i++){temp=*addr;*addr=temp+32;addr++;}addr=shmat(shmid,0,0);printf("%s\n",addr);shmdt(addr);}else{sleep(5);addr=shmat(shmid,0,0);printf("%s\n",addr);}//printf("%s\n",addr);shmctl(shmid,IPC_RMID,0);exit(0);}②截图:③结果和分析:首先显示创建一个要求的共享区,然后挂接上去,得到共享区首地址,向共享区中输入一串大写字符串,然后调用fork(),生成一个子程序,先让挂接到共享区,并且获得首地址,然后修改大写字母变成小写字母,然后脱离,最后再次调用父程序,获得首地址,然后输出共享区的内容。

相关文档
最新文档