unix环境编程卷2之System V共享内存

来源:互联网 发布:java web图书管理系统 编辑:程序博客网 时间:2024/05/18 02:04

system V共享内存概念上类似于Posix共享内存区。每个共享内存区,内核维护shmid_ds结构,定义在<sys/shm.h>

struct shmid_ds {       struct ipc_perm      shm_perm;            /* operation permission struct */       size_t               shm_segz;            /* segment size */       pid_t                shm_lpid;            /* pid of last operation */       pid_t                shm_cpid;            /* creator pid */       shmatt_t             shm_nattach;         /* current # attached */       shmat_t              shm_cnattach;        /* in-core # attached */       time_t               shm_atime;           /* last attach time */       time_t               shm_dtime;           /* last detach time */       time_t               shm_ctime;           /* last change time of this struct*/};

 

shmget函数创建一个新的共享内存区,或者访问一个已经存在的共享内存区

#include <sys/shm.h> int shmget(key_tkey, size_t size, int oflag);    # 返回共享内存区标识符

key既可以是ftok的返回值,也可以是IPC_PRIVATE。size以字节为单位指定内存区的大小。当创建一个新的共享内存区时,size必须大于零,不可改变;当访问一个存在的共享内存区时,size等于零。oflag表示读写权限值得组合,还可以和IPC_CREAT或IPC_CREAT|IPC_EXCL按位或。

小插曲:key_t键和ftok函数

#include <sys/ipc.h> key_t ftok(constchar *pathname, int id) # 把一个存在的路径名和一个整数标识符转换成key_t

<sys/types.h>定义key_t为一个整数,至少32位,称为IPC键。

 

shmat把shmget创建或打开的一个共享内存区附接到调用进程的地址空间

#include <sys/shm.h> void *shmat(intshmid, const void *shmaddr, int flag); # 共享内存区在调用进程的起始地址

1. 如果shmaddr=NULL,系统替调用者选择地址(可移植性最好)

2. 如果shmaddr!=NULL,返回地址取决于调用者是否给flag参数指定SHM_RND值。如果没有指定,共享内存附接到shmaddr指定的地址,否则共享内存区附接到shmaddr指定的地址向下舍入一个SHMLBA常值

 

当一个进程完成某个共享内存区的使用,调用shmdt断接共享内存区,并不删除指定的共享内存区。

#include <sys/shm.h> int shmdt(constvoid *shmaddr);

删除共享内存区通过以IPC_RMID命令调用shmctl完成

#include <sys/shm.h> int shmctl(intshmid, int cmd, struct shmid_ds *buf);

提供三个命令:IPC_RMID 删除shmid标识的共享内存区; IPC_SET 给共享内存区设置三个成员 shm_perm.uid、shm_perm.gid和shm_perm.mode;IPC_STAT 返回共享内存区当前的shmid_ds结构

 

共享内存区限制

查看shmmax内核参数定义单个共享内存段的最大值:more/proc/sys/kernel/shmmax

永久修改shmmax的值:vi /etc/sysctl.conf 编辑文件, 最后一行加入 kernel.shmmax=1073741824

然后执行以下命令使配置生效:/sbin/sysctl -p