第25讲 共享内存编程
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
28
问题
每条记录的存储格式 以前我们存放数据基本是变长的,现在我们需要衡量采用哪种方法更优化, 效率更高。 如何查找读取 以前我们的数据基本都是保存在数组内,查找采用轮询和比较的方式来查 找我们需要的数据,但现在我们是把数据保存在共享内存中,所以我们不能 再用轮询数组的方式查找数据了。 如何定位数据 如何定位数据就是根据提供的数据下标来直接取出数据。
2011-8-8
25
Continue
printf("buf=%s \n", tmp ); if( shmdt( p ) == -1 ) printf(" detach error "); else printf(" detach "); return 0; } 读出共享内存数据为123。
2011-8-8
Linux系统管理与开发 共享内存开发
Copyright @2007 by shao-hui.Guan Pccw of china customization All rights reserved
2011-8-8
1
本节课程内容
共享内存简介 共享内存应用 共享内存编程 深入理解共享内存的设计
2011-8-8
返回值 :成功返回映射区的地址,错误返回-1
2011-8-8
17
Shmdt
功能 :关闭进程和共享内存的连接。 头文件 :#include <sys/shm.h> 函 参 数 :void *shmdt(const void *shmaddr ) 数 :shmaddr 调用者的内存地址。
返回值 :成功返回0,错误返回-1
2011-8-8
19
共享内存程序设计
2011-8-8
20
程序步骤
创建共享内存, 如果存在,就获得指定的共享内存的句柄。 读(写)共享内存的内容。 共享内存访问完毕,关闭和应用程序的连接。 使用完毕,删除共享内存,系统结束。
2011-8-8
21
Sample 1
功能:创建共享内存,同时加载数据,程序结束,脱离共享内存。 #include <sys/shm.h> #include <sys/ipc.h> #include <sys/types.h> #include <unistd.h> int main( int argc, char **argv ) { int shm_id; char tmp[10]; char *p; memset( tmp, 0x00, sizeof( tmp ) ); shm_id = shmget( 8899 ,100,IPC_CREAT | 0644 ); if(shm_id == -1 ) { printf("shmget error\n"); return 0 ; }
2011-8-8
14
Oflag选项
创建共享内存的时候需要设置oflag标准,具体值为 O_CREAT 表示如不存在则创建。并指明权限位。 O_EXCL 如果和O_CREAT联合使用,则表示对象不存在时创建,如 果存在,则报错误EEXIST。 O_NONBLOCK 表示当读一个消息队列的时候,队列为空或者写消息 队列的时候,队列填满,这是进程不阻塞,立即返回。 O_TRUNC 如果以读模式打开一个已经存在的共享内存,该标准将使该 对象的内容置为0。
2011-8-8
23
Sample 1
功能:打开共享内存,同时读取数据,断开共享内存和程序的地址。 #include <sys/shm.h> #include <sys/ipc.h> #include <sys/types.h> #include <unistd.h> #define IPC_KEY 8899 int main( int argc, char **argv ) { int shm_id; char tmp[10]; char *p; memset( tmp, 0x00, sizeof( tmp ) ); shm_id = shmget( IPC_KEY ,0,0 );
2011-8-8
18
Shmctl
功 能 头文件 函 数 参 数 : 操作共享内存 :#include <sys/shm.h> :int shmctl( int shmid, int cmd, struct shmid_ds *buf) :shmid 共享内存的表示符。 cmd和buf结合使用,对共享内存的操作根据cmd的以下值而定: IPC_RMID:删除共享内存shmid。操作权限是超级用户或 shm_perm.cuid或shm_per.uid。 IPC_SET:将buf中以下成员的值赋给共享内存的shmid_ds: shm_perm.uid shm_perm.gid shm_perm.mode /* 低9 位有效 */ 操作权限是超级用户、shm_perm.cuid或 shm_per.uid。 IPC_STAT :获取共享内存的shmid_ds值赋给buf指向的数据结构。 SHM_LOCK:锁住共享内存shmid。操作权限是超级用户。 SHM_UNLOCK:解锁共享内存shmid。操作权限是超级用户 返回值 :成功返回0,错误返回-1
2011-8-8
8
关系事例
共享内存和信号灯的关系如下: 从A城市到B城市,有多条道路。 a 道路 [ 相当于共享内存] b B城市 [ 信号灯] 从a城市到b城市可以有多条道路,因交通管制,现在只有一条道路能到B城市, 这就是信号灯控制并发。当然道路如果都开放,说明访问的资源可以有多个。
2011-8-8
共享内存内维护1个下面的数据结构,每当共享内存发生变化,该结构内相应 的值会发生变化。 struct shmid_ds { struct ipc_perm shm_perm; int shm_segsz; struct tagStruType shm_Struct; unsigned short shm_lpid; unsigned short shm_cpid; unsigned short shm_nattach; usnigned short shm_cnattach; time_t shm_atime; time_t shm_dtime; time_t shm_ctime; }
2011-8-8 22
Continue
printf("shm_id=%d\n", shm_id ); memcpy( tmp, "123", 3 ); p = shmat ( shm_id, 0, 0 ); if( p == ( char *)-1 ) { printf("shmat error\n"); return 0; } sprintf( p, “%s”, tmp ); if( shmdt( p ) == -1 ) printf(" detach error "); else printf(" detach "); return 0; }
2011-8-8
15
队列填满
队列填满我们将在消息队列里面作详细讲解。
2011-8-8
16
shmat
功能 :连接共享内存。
头文件 :#include <sys/shm.h> 函 参 数 :void *shmat( int shmid, const void *shmaddr, int oflag ) 数 :shmid 共享内存表示符 shmaddr 一般为NULL,由系统为调用者选择地址。 oflag 读写权限,一般为0。也可以为SHM_RDONLY.
2011-8-8
7
共享内存+信号灯操作步骤
创建共享内存,申请共享内存 创建信号灯,等待资源数大于0 如果资源大于0,获得访问共享内存的权限,并使资源数减1( p/v操 作,p减少资源,v增加资源),使其他进程不能同时访问共享内存。 读取共享内存内容 共享内存访问完毕,关闭共享内存,释放信号灯( p/v操作) 其他进程获得信号灯值,访问共享内存 删除信号灯 删除共享内存 系统关闭
返回值 :如何成功,返回共享内存的表示符,错误返回-1 备注 :ftok 文件如果被删除,文件重建后,再次调用ftok不能保证返回相同的值。 32位的进程,aix只允许最多11个进程同时访问同一共享内存。hpunix 上 面,为了兼容32和64位,后面一般还要加上shmget(mem_key, size, 0666 | IPC_CREAT | IPC_SHARE32)
2011-8-8 12
/* 操作权限 */ /* 内存段大小 */ /* 内存结构和地址 */ /*最后一次操作内存的进程号 */ /* 创建该内存的进程号 */ /* 当前连接上内存的进程号 */ /* 内核维护的内存连接号 */ /* 最后一次连接时间 */ /* 最后一次脱离时间 */ /* 最后一次改变时间 */
共享内存函数介绍
Shmget Shmat Shmctl Shmdt
2011-8-8
13
Shmget
功能 :创建共享内存。 头文件 :#include <sys/shm.h> 函 参 数 :int shmget( key_t key, size_t size, int oflag ) 数 :key_t size oflag 可以是ftok 的返回值,也可以是IPC_PRIVATE 共享内存区的大小 ,如果共享内存存在,则该参数为0, 读写权限,有IPC_CREATE和IPC_EXCL的按位或。
2
共享内存简介
共享内存是最快的ipc。 允许多个不相关的进程去访问同一部分逻辑内存。
2011-8-8
3
共享内存作用
进程间通信的工具。 主要应用在电信,银行系统的数据交换,数据共享方面。
2011-8-8
4
共享内存优点
共享内存是ipc中传递数据最快的方法 内存区映射到共享进程的地址空间,这些进程间数据的传 输就不再涉及内核, 这样就可以减少系统调用时间,提高程序效率 。 共享内存多用于银行,电信的系统内,在物理内存允许的情况下(大的系统 需要排序,查找,如果在共享内存内,处理可以共享数据,还可以对数据进 行排序,比在缓冲区排序要快),可以申请到4G大小的内存,可以加快 数据的处理速度,提高系统的稳定性,避免过度的占用cpu的时间。
9
共享内存的持续性
System v 共享内存 都是随系统内核存在,如果进程没有删除,将在内核内存 在,数据也将保存下来
2011-8-8
10
Fork,exec对共享内存影响
Fork Exec 附接着的共享内存区在子进程中继续附接。 断开所有附接着的共享内存区
2011-8-8
11
共享内存的数据结构
2011-8-8
29
问题
如何记录创建的每个共享内存的信息。 我们可以利用该系统来创建多个共享内存。如何保存多个共享内存的信息 如何加载数据 如何利用索引查找数据
2011-8-8
30
问题
如何读取一条记录内的某个字段内容 我们定位到该记录的时候,如何定位到该记录的某个字段的内容。 如何防止其他用户非法访问共享内存。 我们如何保证非法用户访问共享内存,防止其他用户读取共享内存的内容, 并且修改该共享内存的内容。 如何保证多进程的同步 如何保证共享内存的同时只能有1个进程访问该共享内存。
26
深入理解共享内存设计
2011-8-8
27
设计实例
本章我们设计一个利用共享内存进行数据管理的系统,系统功能有 1 共享内存的管理 a 共享内存的创建 b 共享内存的关闭 c 共享内存的删除 共享内存的应用 a 包括数据加载 b 数据查找 c 数据定位 d 数据排序 e 数据修改
1
2011-8-8
2011-8-8
24
Continue
if( shm_id == -1 ) { printf("open shm error\n"); return 0 ; } p = shmat ( shm_id, 0, 0 ); if( p == ( char *)-1 ) { printf("shmat error\n"); return 0; } printf("shmat \n"); memcpy( tmp , p, strlen( p ) );
2011-8-8
5
共享内存命令
察看共享内存 ipcs -m 删除共享内存 ipcrm -m id号
2011-8-8
ቤተ መጻሕፍቲ ባይዱ
6
共享内存和信号灯的关系
问题:共享内存的并发控制 由于共享内存是多个进程同时访问,如果设计到修改和查询,在修改 的同时不能做查询处理,则需要一种机制来控制进程访问的顺序,通 常使用信号灯来实现共享内存的并发访问。