共享内存是系统出于多个进程之间通讯的考虑

上传人:第*** 文档编号:32745413 上传时间:2018-02-12 格式:DOC 页数:14 大小:79KB
返回 下载 相关 举报
共享内存是系统出于多个进程之间通讯的考虑_第1页
第1页 / 共14页
共享内存是系统出于多个进程之间通讯的考虑_第2页
第2页 / 共14页
共享内存是系统出于多个进程之间通讯的考虑_第3页
第3页 / 共14页
共享内存是系统出于多个进程之间通讯的考虑_第4页
第4页 / 共14页
共享内存是系统出于多个进程之间通讯的考虑_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《共享内存是系统出于多个进程之间通讯的考虑》由会员分享,可在线阅读,更多相关《共享内存是系统出于多个进程之间通讯的考虑(14页珍藏版)》请在金锄头文库上搜索。

1、共享内存是系统出于多个进程之间通讯的考虑,而预留的的一块内存区。在/proc/sys/kernel/目录下,记录着共享内存的一些限制,如一个共享内存区的最大字节数 shmmax,系统范围内最大共享内存区标识符数 shmmni 等,可以手工对其调整,但不推荐这样做。一、应用共享内存的使用,主要有以下几个 API:ftok()、shmget()、shmat()、shmdt()及 shmctl()。1)用 ftok()函数获得一个 ID 号.应用说明:在 IPC 中,我们经常用用 key_t 的值来创建或者打开信号量,共享内存和消息队列。函数原型:key_t ftok(const char *pat

2、hname, int proj_id);Keys:1)pathname 一定要在系统中存在并且进程能够访问的3)proj_id 是一个 1255 之间的一个整数值,典型的值是一个 ASCII 值。当成功执行的时候,一个 key_t 值将会被返回,否则1 被返回。我们可以使用 strerror(errno)来确定具体的错误信息。考虑到应用系统可能在不同的主机上应用,可以直接定义一个 key,而不用 ftok 获得:#define IPCKEY 0x3443782)shmget()用来开辟/指向一块共享内存的函数应用说明:shmget()用来获得共享内存区域的 ID,如果不存在指定的共享区域就创建

3、相应的区域。函数原型:int shmget(key_t key, size_t size, int shmflg);key_t key 是这块共享内存的标识符。如果是父子关系的进程间通信的话,这个标识符用IPC_PRIVATE 来代替。如果两个进程没有任何关系,所以就用 ftok()算出来一个标识符(或者自己定义一个)使用了。int size 是这块内存的大小int flag 是这块内存的模式(mode)以及权限标识。模式可取如下值: IPC_CREAT 新建(如果已创建则返回目前共享内存的 id)IPC_EXCL 与 IPC_CREAT 结合使用,如果已创建则则返回错误然后将“模式” 和“

4、权限标识”进行“ 或”运算,做为第三个参数。如: IPC_CREAT | IPC_EXCL | 0640 例子中的 0666 为权限标识,4/2/1 分别表示读/写/执行 3 种权限,第一个 0 是 UID,第一个6(4+2)表示拥有者的权限,第二个 4 表示同组权限,第 3 个 0 表示他人的权限。这个函数成功时返回共享内存的 ID,失败时返回-1。关于这个函数,要多说两句。创建共享内存时,shmflg 参数至少需要 IPC_CREAT | 权限标识,如果只有 IPC_CREAT 则申请的地址都是 k=0xffffffff,不能使用;获取已创建的共享内存时,shmflg 不要用 IPC_CR

5、EAT(只能用创建共享内存时的权限标识,如 0640),否则在某些情况下,比如用 ipcrm 删除共享内存后,用该函数并用 IPC_CREAT参数获取一次共享内存(当然,获取失败),则即使再次创建共享内存也不能成功,此时必须更改 key 来重建共享内存。3) shmat()将这个内存区映射到本进程的虚拟地址空间。函数原型:void *shmat( int shmid , char *shmaddr , int shmflag );shmat()是用来允许本进程访问一块共享内存的函数。int shmid 是那块共享内存的 ID。char *shmaddr 是共享内存的起始地址,如果 shmadd

6、r 为 0,内核会把共享内存映像到调用进程的地址空间中选定位置;如果 shmaddr 不为 0,内核会把共享内存映像到 shmaddr 指定的位置。所以一般把 shmaddr 设为 0。int shmflag 是本进程对该内存的操作模式。如果是 SHM_RDONLY 的话,就是只读模式。其它的是读写模式成功时,这个函数返回共享内存的起始地址。失败时返回-1。4) shmdt()函数删除本进程对这块内存的使用,shmdt()与 shmat()相反,是用来禁止本进程访问一块共享内存的函数。函数原型:int shmdt( char *shmaddr );参数 char *shmaddr 是那块共享内

7、存的起始地址。成功时返回 0。失败时返回-1 。5) shmctl() 控制对这块共享内存的使用函数原型:int shmctl( int shmid , int cmd , struct shmid_ds *buf );int shmid 是共享内存的 ID。int cmd 是控制命令,可取值如下:IPC_STAT 得到共享内存的状态IPC_SET 改变共享内存的状态IPC_RMID 删除共享内存struct shmid_ds *buf 是一个结构体指针。IPC_STAT 的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体指定。返回值: 成功:0失败:-1示例程序:#i

8、nclude #include #include #include #include #define IPCKEY 0x366378typedef structchar agen10;unsigned char file_no; st_setting;int main(int argc, char* argv) int shm_id;key_t key;st_setting *p_setting;/首先检查共享内存是否存在,存在则先删除shm_id = shmget(IPCKEY ,1028,0640); if(shm_id != -1)p_setting = (st_setting*)shm

9、at(shm_id,NULL,0);if ( p_setting != (void *)-1)shmdt(p_setting);shmctl(shm_id,IPC_RMID,0) ;shm_id=shmget(IPCKEY,1028,0640|IPC_CREAT|IPC_EXCL); if(shm_id=-1)printf(shmget errorn);return -1;/将这块共享内存区附加到自己的内存段p_setting=(st_setting*)shmat(shm_id,NULL,0);strncpy(p_setting-agen,jinyh,10); printf( agen:%sn

10、,p_setting-agen );p_setting-file_no = 1;printf( file_no:%dn,p_setting-file_no );system(ipcs -m);/此时可看到有进程关联到共享内存的信息,nattch 为 1/将这块共享内存区从自己的内存段删除出去if(shmdt(p_setting) = -1)perror( detach error );system(ipcs -m);/此时可看到有进程关联到共享内存的信息,nattch 为 0/删除共享内存 if (shmctl( shm_id , IPC_RMID , NULL ) = -1)perror(

11、delete error );/exit(0);注意:在使用共享内存,结束程序退出后。如果你没在程序中用 shmctl()删除共享内存的话,一定要在命令行下用 ipcrm 命令删除这块共享内存。你要是不管的话,它就一直在那儿放着了。简单解释一下 ipcs 命令和 ipcrm 命令。取得 ipc 信息:ipcs -m|-q|-s-m 输出有关共享内存(shared memory)的信息-q 输出有关信息队列(message queue)的信息-s 输出有关“遮断器”(semaphore)的信息%ipcs -m删除 ipcipcrm -m|-q|-s shm_id%ipcrm -m 105二、陷阱

12、(参考 http:/ 陷阱采用 ftok 来生成 key 的情况下,如果 ftok 的参数 pathname 指定文件被删除后重建,则文件系统会赋予这个同名文件(或目录)新的 i 节点信息,于是这些进程所调用的 ftok 虽然都能正常返回,但得到的键值却并不能保证相同。2)3. AIX 中 shmat 的问题AIX 系统中,System V 各类进程间通信机制在使用中均存在限制。区别于其它 UNIX 操作系统对 IPC 机制的资源配置方式,AIX 使用了不同的方法;在 AIX 中定义了 IPC 机制的上限, 且是不可配置的。就共享内存机制而言,在 4.2.1 及以上版本的 AIX 系统上,存在

13、下列限制:对于 64 位进程,同一进程可连接最多 268435456 个共享内存段; 对于 32 位进程,同一进程可连接最多 11 个共享内存段,除非使用扩展的 shmat; 上述限制对于 64 位应用不会带来麻烦,因为可供连接的数量已经足够大了;但对于 32 位应用,却很容易带来意外的问题,因为最大的连接数量只有 11 个。下面的例程 test02.c 演示了这个问题,为了精简代码,它反复连接的是同一个共享内存对象;实际上,无论所连接的共享内存对象是否相同,该限制制约的是连接次数:#include #include #include #include #include #define MAX

14、_ATTACH_NUM 15void main(int argc, char* argv)key_t mem_key;long mem_id;void* mem_addrMAX_ATTACH_NUM;int i;if ( ( mem_key = ftok(/tmp/mykeyfile, 1) ) = (key_t)(-1) ) printf(Failed to generate shared memory access key, ERRNO=%dn,errno);goto MOD_EXIT;if ( ( mem_id = shmget(mem_key, 256, IPC_CREAT) ) =

15、(-1) ) printf(Failed to obtain shared memory ID, ERRNO=%dn, errno);goto MOD_EXIT;for ( i=1; i SHMMAX */struct vm_area_struct *attaches; /* descriptors for attaches */;其中:shm_pages 是该共享内存对象的页表,每个共享内存对象一个,它描述了如何把该共享内存区域映射到进程的地址空间的信息。shm_npages 是该共享内存区域的大小,以页为单位。shmid_ds 是一个数据结构,它描述了这个共享内存区的认证信息,字节大小,最后一次粘附时间、分离时间、改变时间,创建该共享区域的进程,最后一次 对它操作的进程,当前有多少个进程在使用它等信息。其定义如下:struct shmid_ds struct ipc_perm shm_perm; /* operation perms */int shm_segsz; /* size of segment (bytes) */_kernel_time_t shm_atime; /* last attach

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 工程造价

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号