Linux共享内存

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
20
//定义共享内存内部
共享内存通信应用举例
while(1) //循环输入信息 { puts("Enter some text:"); fgets(buffer,BUFSIZ,stdin); //从键盘输入信息 strcat(viraddr,buffer); //采用追加方式写到共享内存 if(strncmp(buffer,"end",3)==0) //输入为“end”时结束 break; } shmdt(viraddr); //断开附接 exit(0); }
命令格式:
shmctl(int shmid, int cmd, struct shmid_ds *buf)
功能: 对与共享存储区关联的各种参数进行操作,从而对共 享存储区进行控制包括删除共享存储区。 参数说明: shmid——共享存储区的内部标识符,由shmget()调 用返回; buf——用户级数据结构地址,其结构类型与系统定义 的shmid_ds一致,可以用0。
main() { int shmid;
标识shmid char *viraddr; //定义附接共享内存 的虚拟地址 char buffer[BUFSIZ]; //定义存放信息的字符串 shmid=shmget(1234,BUFSI Z,0666|IPC_CREAT); //创建共享内存 viraddr=(char*)shmat(shmi d, 0,0); //附接到进程的虚拟地址空间
8
2.映射共享内存
命令格式:
字符型共享内存:
shmat( int shmid, char *shmaddr, int msgflg, ulong *raddr );
数值型共享内存:
shmat( int shmid, int *shmaddr, int msgflg, ulong *raddr );
12
3.撤消映射
使用完毕后,应该撤消映射的操作
命令格式:
int shmdt(const void *shmaddr)
功能:
将一个共享存储区从指定进程的虚拟地址空间断开。 参数说明: shmaddr——系统调用shmat()所返回的虚地址。 返回值: 正确返回:0 错误返回-1。
13
4.对共享内存的操作
shmid=shmget(1234,BUFSI Z,0666|IPC_CREAT); //获取共享内存 viraddr=shmat(shmid, 0,0); //附接到进程的虚拟地址空间 printf("Your message is :\n%s",viraddr); //输出信息内容 shmdt(viraddr); //断开附接 shmctl(shmid,IPC_RMID,0); //撤消共享内存 exit(0); }
14
cmd——规定操作的类型。其规定如下: IPC_STAT 返回包含在指定的shmid相关数据结构中 的状态信息,并把它放置在用户存储区中的*buf指针 所指的数据结构中。执行此命令的进程必须有读取允 许权。 IPC_SET 对于指定的shmid,为它设置有效用户和 小组标识符和操作存取权。 IPC_RMID删除指定的shmid以及与它相关的共享存 储区的数据结构。 SHM_LOCK在内存中锁定指定的共享存储区,必须 是超级用户才可以进行此项操作。
2
共享内存通信应用
共享内存的通信方式是通过将可以共享的内存缓 冲区直接附加到进程的虚拟地址空间中来实现的, 因此,这些进程之间的读写操作的同步问题操作系 统无法实现,必须由诸共享该内存的进程去控制。 另外,由于内存实体存在于计算机系统中,所以只 能由处于同一个计算机系统中的诸进程共享。以上 两点是共享内存通信的缺点,但是它提供了诸进程 直接读写信息,无须复制,因而方便快捷的进程间 通信方式,适用于信息量大且操作频繁的场合。
6
1.创建或获取一个共享内存
命令格式:
shmget( key, size, flag ) 功能: 获得一个内部标识为shmid的共享存储区。 语句格式: int shmid = int shmget ( key_t key, int size, int flag );
7
参数说明:
key——共享存储区关键字,可以由用户指定,如果使 用IPC_PRIVATE其值由系统产生。 size ——存储区的大小(字节数)。如果存储区定义 为字符型,则大小为定义的字符个数;如果存储区 定义为整型,大小可以使用sizeof (int)加以定义。 flag—— 用 户 设 置 的 标 志 或 访 问 方 式 , 与 消 息 缓 冲 shmget 中 的 含 义 相 同 , 在 实 验 中 , 可 以 使 用 0666|IPC_CREAT,表示任意进程可读可写。 返回值: 正确返回:共享存储区的内部标识符shmid 错误返回:-1
功能:
逻辑上将内部标识符为shmid的共享存储区附接到进 程的虚拟地址空间shmaddr。
9
语句格式:
字符型共享内存:
viraddr = ( char* ) shmat ( shmid, shmaddr, shmflag );
数值型共享内存:
viraddr = ( int* ) shmat shmaddr, shmflag ); ( shmid,
17
接收进程: 1. 用系统调用函数shmget();创建或者获取指定key值的共享内存; 2. 用系统调用函数shmat();将该共享内存附接到自己的程序空间; 3.将共享内存中的信息输出;或取出存放到其它数据块中; 4.使用系统调用函数shmdt();断开共享内存。 5.如果不再使用共享内存时,使用系统调用函数shmctl()将其撤消, 格式为:shmctl(shmid,IPC_RMID,0);
4
2.共享内存原理示意图
进程1地址空间
内核共享内存区
进程2地址空间
分配的共享内 存
进程1的共享内
进程2的共享内 存映射区
存映射区
5
共享内存通信的系统调用
与消息缓冲通信类似,Linux对共享内 存通信也提供了4个系统调用函数: shmget() 创建共享内存 shmat() 映射共享内存 shmdt() 撤消映射 shmctl() 共享内存的控制 下面分别予以介绍。
wk.baidu.com15
例如,实验中,需要撤消共享存储区时可以使 用以下格式完成: shmctl(shmid,IPC_RMID,0);
返回值: 正确返回:0 错误返回:-1 所用头函数: #include <sys/ipc.h> #include <sys/shm.h> 与消息缓冲类似,对于共享内存的删除也要有权 限,如超级用户进程等,所以上机实习时应该使用 root登录。
16
共享内存通信实现方法
发送进程: 1.使用系统调用函数shmget()创建或者获取指定key值的共享内存;
2.使用系统调用函数shmat(),将该共享内存附接到自己的虚拟地址空间; 3.将需要发送的信息写入共享内存,方法有以下几种: ①.每条信息都以追加的方式写入,可以使用C语言提供的字符串追加函数 strcat(viraddr, buffer),该函数的功能是将buffer中的字符串追加到 由viraddr附接的共享存储区的尾部。其中,viraddr是请求得到的共享内 存的地址,buffer是用户进程中请求的用来存放信息的字符缓冲区。 ②.每条信息都以覆盖的方式写入,可以使用strcpy(viraddr,buffer)函数 将buffer中的字符串复制到viraddr指向的共享内存中,则该共享内存中就 只有当前复制进来的信息,以前复制的信息被覆盖了。 ③.共享内存定义为数值型变量,则可以将*viraddr作为数值型变量对其进行 操作。例如将其赋值为0可以使用:*viradd=0。 ④.共享内存定义为数值型数组,则可以将viraddr[i]作为下标变量使用。例 如将其赋值为0可以使用: viradd[i]=0。 4.使用系统调用函数shmdt(),断开共享内存。
18
结论:
1. 共享内存允许两个或 多个进程共享一给定的存储 区,因为数据不需要来回复 制,所以是最快的一种进程 间通信机制。共享内存可以 通过mmap()映射普通文件 (特殊情况下还可以采用匿 名映射)机制实现,也可以 通过系统V共享内存机制实 现。应用接口和原理很简单 ,内部机制复杂。为了实现 更安全通信,往往还与信号 灯等同步机制共同使用。

2.共享内存涉及到了存 储管理以及文件系统等方面 的知识,深入理解其内部机 制有一定的难度,关键还要 紧紧抓住内核使用的重要数 据结构。系统V共享内存是 以文件的形式组织在特殊文 件系统shm中的。通过 shmget可以创建或获得共 享内存的标识符。取得共享 内存标识符后,要通过 shmat将这个内存区映射到 本进程的虚拟地址空间。
21
共享内存通信应用举例
接收进程 rcvshm.c
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<linux/shm.h> main() { int shmid; char *viraddr;
Linux共享内存通信
1.
共享内存通信概述
针对消息缓冲需要占用CPU进行消息复制的缺点,操作系统提 供了一种进程间直接进行数据交换的通信方式——共享内存。顾 名思义,这种通信方式允许多个进程共享同一块物理内存空间来 实现进程之间的信息交换,其特点是没有中间环节,直接将共享 的内存页面通过附接,映射到相互通信的进程各自的虚拟地址空 间中,从而使多个进程可以直接访问同一个物理内存页面,如同 访问自己的私有空间一样(但实质上不是私有的而是共享的)。 因此这种进程间通信方式是在同一个计算机系统中的诸进程间实 现通信的最快捷的方法,而它的局限性也在于此,即共享内存的 诸进程必须共处同一个计算机系统,有物理内存可以共享才行。
10
实验中分别使用以下格式附接:
字符型:
viraddr = (char *) shmat(shmid,0,0);
数值型:
viraddr = (int *) shmat(shmid,0,0);
返回值: 正确返回:共享存储区附接后的虚地址; 错误返回:-1
11
参数说明:
shmid——共享存储区的描述符,可以由shmget()的返 回值得到; shmaddr——用户提供的共享存储区附接的虚 地址。 (若shmaddr为0 ,则表示系统自动分配地址并把该 段共享内存映射到调用进程的地址空间); flag——规定了对该存储区的操作权限,以及系统是否 要对用户规定的地址做舍除操作。如果flag中设置了 SHM_RND表示操作系统在必要时舍去这个 地址 。 (如果设置了SHM_RDONLY则表示只允许读,flag 为0表示可读可写)。 viraddr——附接的虚地址,若定义为char *viraddr,则 该 共 享 内 存 作 为 字 符 存 储 区 使 用 , 若 定 义 为 int *viraddr,则该共享内存作为整型存储区使用。
19
共享内存通信应用举例
[例1]用共享内存的通信方法来实现 例4-5的功能,通过先运行发送 进程然后再运行接收进程的方 式来实现同步。 发送进程 sndshm.c #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<linux/shm.h>
3
共享内存通信
1. 共享内存原理



共享内存是由IPC为一个进程所创建并且出现在这个进程 的地址空间中的一段特殊的地址序列。其他的进程可以将 同样的共享内存段关联到他们自己的地址空间中。所有的 进程都可以访问这段内存地址,就如同这段内存是由 malloc所分配的。如果一个进程写入共享内存,这些改变 立即就可以为访问相同共享内存的其他进程所见。 就其自身而言,共享内存并没有提供任何共享方法。并没 有自动的方法来阻止在第一个进程完成写入共享内存之前 第二个进程开始读取共享内存。同步访问是程序员的责任。 下图显示共享内存是如何工作的。每一个箭头显示的是每 一个进程的逻辑地址空间到可用的物理内存的映射。
相关文档
最新文档