技术研究论文集共享内存Word下载.docx

上传人:b****1 文档编号:3729939 上传时间:2023-05-02 格式:DOCX 页数:35 大小:471.38KB
下载 相关 举报
技术研究论文集共享内存Word下载.docx_第1页
第1页 / 共35页
技术研究论文集共享内存Word下载.docx_第2页
第2页 / 共35页
技术研究论文集共享内存Word下载.docx_第3页
第3页 / 共35页
技术研究论文集共享内存Word下载.docx_第4页
第4页 / 共35页
技术研究论文集共享内存Word下载.docx_第5页
第5页 / 共35页
技术研究论文集共享内存Word下载.docx_第6页
第6页 / 共35页
技术研究论文集共享内存Word下载.docx_第7页
第7页 / 共35页
技术研究论文集共享内存Word下载.docx_第8页
第8页 / 共35页
技术研究论文集共享内存Word下载.docx_第9页
第9页 / 共35页
技术研究论文集共享内存Word下载.docx_第10页
第10页 / 共35页
技术研究论文集共享内存Word下载.docx_第11页
第11页 / 共35页
技术研究论文集共享内存Word下载.docx_第12页
第12页 / 共35页
技术研究论文集共享内存Word下载.docx_第13页
第13页 / 共35页
技术研究论文集共享内存Word下载.docx_第14页
第14页 / 共35页
技术研究论文集共享内存Word下载.docx_第15页
第15页 / 共35页
技术研究论文集共享内存Word下载.docx_第16页
第16页 / 共35页
技术研究论文集共享内存Word下载.docx_第17页
第17页 / 共35页
技术研究论文集共享内存Word下载.docx_第18页
第18页 / 共35页
技术研究论文集共享内存Word下载.docx_第19页
第19页 / 共35页
技术研究论文集共享内存Word下载.docx_第20页
第20页 / 共35页
亲,该文档总共35页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

技术研究论文集共享内存Word下载.docx

《技术研究论文集共享内存Word下载.docx》由会员分享,可在线阅读,更多相关《技术研究论文集共享内存Word下载.docx(35页珍藏版)》请在冰点文库上搜索。

技术研究论文集共享内存Word下载.docx

版权说明

Allrightsreserved.Neitherthewholenoranypartsofthisdocumentmaybereproduced,storedinanyretrievalsystemortransmitted,inanyformorbyanymeans,withoutthepriorwrittenconsentofthecopyrightowner.

Copyright©

2007by联创科技-综合结算产品部

Allrightsreserved.

目录:

2007by联创科技-综合结算产品部3

1文档介绍5

1.1.文档编写目的5

1.2.文档阅读对象5

1.3.涵盖范围5

1.4.缩略语定义5

1.5.参考文档5

1.6.文档概要5

2共享内存5

2.1概念5

2.2原理6

2.3类型与区别7

2.4常用函数说明8

2.4.1POSIX函数说明8

2.4.1.1打开或创建一个共享内存区8

2.4.1.2删除一个共享内存区9

2.4.1.3映射9

2.4.1.4解除映射10

2.4.1.4同步11

2.4.1.5映射区复制11

2.4.1.6改变共享内存12

2.4.1.7获得共享内存信息12

2.4.1.8应用举例12

2.4.2SYSTEMV原理14

2.4.3SYSTEMV函数说明15

2.4.3.1以创建或打开一块共享内存区15

2.4.3.2共享内存链接进程17

2.4.3.3共享内存脱离进程18

2.4.3.4删除共享内存18

2.4.3.5应用举例19

2.5常见问题21

2.5.1AIX中shmat的问题21

2.5.2HP-UX32位和64位的兼容24

2.5.3对同一共享内存的连接数限制24

2.5.4Solaris系统中的shmdt调用27

2.5.5shmctl函数的风险28

1

文档介绍

1.1.文档编写目的

随着结算系统和IDEP系统的发展,进程间通信越频繁,本文介绍了UNIX系统提供的进程间最快的通信方式——共享内存的基本函数和原理。

1.2.文档阅读对象

1)unix学习者

2)系统维护人员

3)系统开发人员

1.3.涵盖范围

1.4.缩略语定义

1.5.参考文档

1)unix环境高级编程

2)Linux常用C函数(中文版)

1.6.文档概要

2共享内存

2.1概念

所谓共享内存就是多个进程间共同使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的虚空间中来实现的。

由于映射到不同进程的虚空间中,不同进程可以直接使用,不需要进行内存的复制,所以共享内存的效率很高。

2.2原理

在系统内核为一个进程分配内存地址时,通过分页机制可以让一个进程的物理地址不连续,同时也可以让一段内存同时分配给不同的进程。

如下图2-1所示:

图:

2-1

这块共享虚拟内存的页面,出现在每一个共享该页面的进程的页表中。

但是它不需要在所有进程的虚拟内存中都有相同的虚拟地址。

如下图2-2所示:

2-2

2.3类型与区别

共享内存分为两种:

POSIX的共享内存和systemV的共享内存。

二者是用同一种机制完成的,但是存在着一定的区别。

1.不同的是用户接口:

POSIX的共享内存,通过用户空间挂载的tmpfs文件系统实现的。

SYSTEMV的共享内存,是由内核本身的tmpfs实现的。

2.不同的调用接口:

POSIX的共享内存机制实际上在库过程中以及用户空间的其他部分被展示为完全的文件系统的调用过程,在调用完shm_open之后,需要调用mmap来将tmpfs的文件映射到地址空间,接着就可以操作这个文件了,需要注意的是,别的进程也可以操作这个文件,因此这个文件其实就是共享内存。

SYSTEMV的共享内存,内核直接实现了shmget/at系统调用,虽然最终也是靠tmpfs来实现的,但是接口设计上和posix完全不同。

POSIX旨在提供所有系统都一致的接口。

SYSTEMV只在于实现自己的逻辑,共享内存其实只是sysv中ipc的一部分,最终的管理数据结构也是ipc的而不是共享内存的

3.不同的消退方式:

不管是SYSTEMV的还是POSIX的共享内存,在主机重启之后都不复存在,因为数据是都保存在物理存储器上或交换分区中。

他们不同的是:

POSIX是以用户空间文件实现的,并且用户空间操作的是文件描述符,文件描述符是属于task_struct的,因此进程退出之后共享内存将递减共享计数,如果为0的时候则销毁。

因此POSIX的共享内存虽然使用OPEN来创建或打开共享内存并没有用close而是用unlink来关闭的,作用就是在计数为0的时候销毁它。

SYSTEMV的共享内存,虽然也是由文件实现的,但是文件并没有加到进程的打开文件表,而是作为进程的一种内在属性被使用的,因此在进程退出时并不关闭文件,只要机器不重启或不显式销毁,那么共享内存将一直存在,进程和文件其实是互不相关的两个概念,只是进程打开的文件才和进程相关,在进程结束的时候只是能保证与之相关的文件被关闭,而别的文件比如SYSTEMV的共享内存使用的文件结构没有和进程关联,因此不会被关闭。

其实close并不操作什么,而是仅仅刷新缓冲区,然后递减文件的使用者计数。

4.不同的通用性:

SYSTEMV共享内存存在时间比较老,许多系统都支持,但是接口复杂并且可能各平台上实现略有区别。

POSIX共享内存是新标准,现在多数UNIX已实现,语法简单,并且各平台上实现都一样。

5.不同的大小限制:

POSIX的大小可以在任何时刻通过调用ftruncate修改,而SYSTEMV共享内存对象的大小是在调用shmget创建时已经固定下来的。

POSIX共享内存的大小、数量只受系统文件限制,而SYSTEMV共享内存对象的大小、数量受内核参数限制。

2.4常用函数说明

2.4.1POSIX函数说明

POSIX共享内存区涉及两个步骤:

1、指定一个名字参数调用shm_open,以创建一个新的共享内存区对象或打开一个以存在的共享内存区对象。

2、调用mmap把这个共享内存区映射到调用进程的地址空间。

传递给shm_open的名字参数随后由希望共享该内存区的任何其他进程使用。

2.4.1.1打开或创建一个共享内存区

●函数介绍:

名称

shm_open

功能

打开或创建一个共享内存区

头函数

#include<

sys/mman.h>

函数原型

intshm_open(constchar*name,intoflag,mode_tmode);

参数

name共享内存区的名字

cflag标志位

mode权限位

返回值

成功返回0,出错返回-1

●参数详解:

cflag:

必须含有O_RDONLY和O_RDWR标志,还可以指定如下标志:

O_CREAT,O_EXCL或O_TRUNC。

mode:

指定权限位,它指定O_CREAT标志的前提下使用。

●返回值:

shm_open的返回值是一个整数描述字,它随后用作mmap的第五个参数。

2.4.1.2删除一个共享内存区

shm_unlink

删除一个共享内存区

intshm_unlink(constchar*name);

●注意点:

shm_unlink函数删除一个共享内存区对象的名字,删除一个名字仅仅防止后续的open,mq_open或sem_open调用取得成功。

2.4.1.3映射

mmap

把I/O文件映射到一个存储区域中

void*mmap(void*addr,size_tlen,intprot,intflag,intfiledes,off_toff);

addr指向映射存储区的起始地址

len映射的字节

prot对映射存储区的保护要求

flagflag标志位

filedes要被映射文件的描述符

off要映射字节在文件中的起始偏移量

若成功则返回映射区的起始地址,若出错则返回MAP_FAILED

addr:

用于指定映射存储区的起始地址。

通常将其设置为NULL,这表示由系统选择该映射区的起始地址。

filedes:

指要被映射文件的描述符。

在映射该文件到一个地址空间之前,先要打开该文件。

len是映射的字节数。

off:

是要映射字节在文件中的起始偏移量。

通常将其设置为0。

prot:

说明对映射存储区的保护要求。

可将prot参数指定为PROT_NONE,或者是PROT_READ(映射区可读),PROT_WRITE(映射区可写),PROT_EXEC(映射区可执行)任意组合的按位或,也可以是PROT_NONE(映射区不可访问)。

对指定映射存储区的保护要求不能超过文件open模式访问权限。

flag:

影响映射区的多种属性:

MAP_FIXED返回值必须等于addr.因为这不利于可移植性,所以不鼓励使用此标志。

MAP_SHARED这一标志说明了本进程对映射区所进行的存储操作的配置。

此标志指定存储操作修改映射文件。

MAP_PRIVATE本标志导致对映射区建立一个该映射文件的一个私有副本。

所有后来对该映射区的引用都是引用该副本,而不是原始文件。

必须指定MAP_FIXED或MAP_PRIVATE标志其中的一个,指定前者是对存储映射文件本身的一个操作,而后者是对其副本进行操作。

mmap成功返回后,fd参数可以关闭。

该操作对于由mmap建立的映射关系没有影响。

2.4.1.4解除映射

munmap

解除存储映射

intmunmap(caddr_taddr,size_tlen);

若成功则返回0,若出错则返回-1

addr参数是由mmap返回的地址,len是映射区的大小。

解除映射后,再次访问这些地址导致向调用进程产生一个SIGSEGV信号。

2.4.1.4同步

msync

同步文件到存储器

intmsync(void*addr,size_tlen,intflags);

protflags

addr和len:

通常指代内存中的整个内存映射区,不过也可以指定该内存区的一个子集。

flags:

为MS_ASYNC(执行异步写),MS_SYNC(执行同步写),MS_INVALIDATE(使高速缓存的数据实效)。

其中MS_ASYNC和MS_SYNC这两个常值中必须指定一个,但不能都指定。

它们的差别是:

一旦写操作已由内核排入队列,MS_ASYNC即返回,而MS_SYNC则要等到写操作完成后才返回。

如果还指定了MS_INVALIDATE,那么与其最终拷贝不一致的文件数据的所有内存中拷贝都失效,后续的引用将从文件取得数据

2.4.1.5映射区复制

memcpy

复制映射存储区

string.h>

void*memcpy(void*dest,constvoid*src,size_tn);

dest复制后的映射存储区

src待复制的映射存储区

n待复制的映射存储区的大小

返回dest的首地址

2.4.1.6改变共享内存

ftruncate

调整文件或共享内存区大小

unistd.h>

intftruncate(intfd,off_tlength);

fd描述符

length大小

2.4.1.7获得共享内存信息

fstat

获得文件或共享内存区的信息

sys/types.h>

sys/stat.h>

intstat(constchar*file_name,structstat*buf);

file_name文件名

bufstat结构

对于普通文件stat结构可以获得12个以上的成员信息,然而当fd指代一个共享内存区对象时,只有四个成员含有信息。

structstat{

mode_tst_mode;

uid_tst_uid;

gid_tst_gid;

off_tst_size;

};

2.4.1.8应用举例

我们系统的例子----流程调度

在流程调度里面,这一部分主要用于共享内存中批次链表中的批次信息实时落地用的。

2.4.2SYSTEMV原理

系统V共享内存通过shmget获得或创建一个IPC共享内存区域,并返回相应的标识符。

内核在保证shmget获得或创建一个共享内存区,初始化该共享内存区相应的shmid_kernel结构注同时,还将在特殊文件系统shm中,创建并打开一个同名文件,并在内存中建立起该文件的相应dentry及inode结构,新打开的文件不属于任何一个进程(任何进程都可以访问该共享内存区)。

所有这一切都是系统调用shmget完成的。

每一个共享内存区都有一个控制结构structshmid_kernel,shmid_kernel是共享内存区域中非常重要的一个数据结构,它是存储管理和文件系统结合起来的桥梁,定义如下:

structshmid_kernel

{

structkern_ipc_permshm_perm;

structfile*shm_file;

intid;

unsignedlongshm_nattch;

unsignedlongshm_segsz;

time_tshm_atime;

time_tshm_dtime;

time_tshm_ctime;

pid_tshm_cprid;

pid_tshm_lprid;

shm_perm 

 

成员储存了共享内存对象的存取权限及其它一些信息。

shm_segsz 

成员定义了共享的内存大小(以字节为单位)。

shm_atime 

成员保存了最近一次进程连接共享内存的时间。

shm_dtime 

成员保存了最近一次进程断开与共享内存的连接的时间。

shm_ctime 

成员保存了最近一次shmid_ds结构内容改变的时

shm_cpid 

成员保存了创建共享内存的进程的pid。

shm_lpid 

成员保存了最近一次连接共享内存的进程的pid。

shm_nattch 

成员保存了与共享内存连接的进程数目。

该结构中最重要的一个域应该是shm_file,它存储了将被映射文件的地址。

每个共享内存区对象都对应特殊文件系统shm中的一个文件,一般情况下,特殊文件系统shm中的文件是不能用read()、write()等方法访问的,当采取共享内存的方式把其中的文件映射到进程地址空间后,可直接采用访问内存的方式对其访问。

这里我们采用[1]中的图表给出与系统V共享内存相关数据结构:

内核通过数据结构structipc_idsshm_ids维护系统中的所有共享内存区域。

上图中的shm_ids.entries变量指向一个ipc_id结构数组,而每个ipc_id结构数组中有个指向kern_ipc_perm结构的指针。

对于系统V共享内存区来说,kern_ipc_perm的宿主是shmid_kernel结构,shmid_kernel是用来描述一个共享内存区域的,这样内核就能够控制系统中所有的共享区域。

同时,在shmid_kernel结构的file类型指针shm_file指向文件系统shm中相应的文件,这样,共享内存区域就与shm文件系统中的文件对应起来。

2.4.3SYSTEMV函数说明

SYSTEMV共享内存区涉及以下步骤:

1.开辟一块共享内存shmget()

2.允许本进程使用共某块共享内存shmat()

3.写入/读出

4.禁止本进程使用这块共享内存shmdt()

5.删除这块共享内存shmctl()或者命令行下ipcrm

2.4.3.1以创建或打开一块共享内存区

shmget

sys/shm.h>

intshmget(key_tkey,intsize,intshmflag);

key共享内存的标识符

size大小

shmflag内存的模式(mode)以及权限标识

成功返回标识,出错返回-1

key:

在IPC的通信模式下,不管是使用消息队列还是共享内存,甚至是信号量,每个IPC的对象(object)都有唯一的名字,称为“键”(key)。

通过“键”,进程能够识别所用的对象。

“键”与IPC对象的关系就如同文件名称之于文件,通过文件名,进程能够读写文件内的数据,甚至多个进程能够共用一个文件。

而在IPC的通讯模式下,通过“键”的使用也使得一个IPC对象能为多个进程所共用。

Linux系统中的所有表示SystemV中IPC对象的数据结构都包括一个ipc_perm结构,其中包含有IPC对象的键值,该键用于查找SystemV中IPC对象的引用标识符。

如果不使用“键”,进程将无法存取IPC对象,因为IPC对象并不存在于进程本身使用的内存中。

Key使用者要显示定义。

size:

size是要建立共享内存的长度。

所有的内存分配操作都是以页为单位的。

所以如果一段进程只申请一块只有一个字节的内存,内存也会分配整整一页(在i386机器中一页的缺省大小PACE_SIZE=4096字节)这样,新创建的共享内存的大小实际上是从size这个参数调整而来的页面大小。

即如果size为1至4096,则实际申请到的共享内存大小为4K(一页);

4097到8192,则实际申请到的共享内存大小为8K(两页),依此类推。

shmflg:

shmflg主要和一些标志有关。

其中有效的包括IPC_CREAT和IPC_EXCL,它们的功能与open()的O_CREAT和O_EXCL相当。

IPC_CREAT如果共享内存不存在,则创建一个共享内存,否则打开操作。

IPC_EXCL只有在共享内存不存在的时候,新的共享内存才建立,否则就产生错误。

IPC_ALLOC使用已经创建的共享内存。

如果单独使用IPC_CREAT,shmget()函数要么返回一个已经存在的共享内存的操作符,要么返回一个新建的共享内存的标识符。

如果将IPC_CREAT和IPC_EXCL标志一起使用,shmget()将返回一个新建的共享内存的标识符;

如果该共享内存已存在,或者返回-1。

IPC_EXEL标志本身并没有太大的意义,但是和IPC_CREAT标志一起使用可以用来保证所得的对象是新建的,而不是打开已有的对象。

对于用户的读取和写入许可指定SHM_R和SHM_W,(SHM_R>

3)和(SHM_W>

3)是一组读取和写入许可,而(SHM_R>

6)和(SHM_W>

6)是全局读取和写入许可。

返回值:

成功返回共享内存的标识符。

不成功返回-1,errno储存错误原因。

EINVAL参数size小于SHMMIN或大于SHMMAX。

EEXIST预建立key所致的共享内存,但已经存在。

EIDRM 

参数key所致的共享内存已经删除。

ENOSPC 

超过了系统允许建立的共享内存的最大值(SHMALL)。

ENOENT 

参数key所指的共享内存不存在,参数shmflg也未设IPC_CREAT位。

EACCES 

没有权限。

ENOMEM 

核心内存不足

2.4.3.2共享内存链接进程

shmat

将一个存在的共享内存段连接到本进程空间

void*shmat(intshm_id,constvoid*addr,intflag);

shm_id文件名

addr共享内存地址

flag标识

成功返回被映射的段地址,出错返回-1

shm_id:

共享存储器标识。

指向共享存储器连上的起始地址。

对于shmat()函数,如果为NULL将由系统选择合适的地址。

flag:

共享存储器相关的标志,可能值有:

SHM_

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 临时分类 > 批量上传

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2