共享内存是不同进程通信的一种很好的方式。创建共享内存后,映射到不同的进程,多个进程便可以访问和使用共享内存,一个进程的修改会立刻被其他进程看到。
使用共享内存的流程是
创建共享内存 —> 把共享内存映射到进程的地址空间 —> 使用共享内存 —> 把共享内存和进程分离 —> 删除共享内存
对共享内存的访问需要程序员自己提供同步机制。共享内存的工作方式如下图所示
Linux提供的与共享内存相关的函数有四个,他们的声明在头文件shm.h中。
shmget函数 创建共享内存
shmget用来创建共享内存,它的声明如下
int shmget(key_t key, size_t size, int shmflg);
第一个参数key_t key
和信号量函数一样,参数key用来生成共享内存的唯一标识,不同进程中 相同的key返回相同的标示符。标示符是用来标记共享内存的标示。
第二个参数 size_t size
它用来指定共享内存的大小。
第三个参数 int shmflg
和信号量函数中sem_flags类似,是含有9个比特的权限标志。
一般使用IPC_CREAT|0666
返回值
如果共享内存创建失败则返回-1 成功返回非负整数,该整数用于后面三个函数中,用来唯一确定哪个共享内存。
shmat函数 绑定共享内存到进程
void *shmat(int shm_id, const void *shm_addr, int shmflg)
第一个参数 int shm_id
是由shmget返回的共享内存标示符。
第二个参数 shm_addr
可以用于指定把共享内存连接到进程的哪个地址位置。使用NULL表示让系统自动选择位置。
第三个参数 shmflg
权限标识。常用的有
SHM_RND:用来和shm_addr配合控制连接的地址位置
SHM_RDONLY :使连接的内存只读
返回值
返回值是指向共享内存的指针。如果失败返回-1
shmdt函数 将共享内存和进程分离
int shmdt (const void *shm_addr)
shmdt函数的所用是把共享内存从当前进程分离。分离并不是删除了共享内存,只是对该进程不可用了。
它的参数是shmat返回的地址。
成功时返回0 失败返回-1
shmctl函数
int shmctl(int shm_id, int cmd, struct shmid_ds *buf)
该函数用于对共享内存进行控制。
第一个参数 shm_id
是shmget返回的内存标示符。
第二个参数cmd
是要采取的动作,有三种可能的取值
IPC_STAT : 把shmid_ds结构中的数据设置为共享内存的当前关联值。
IPC_SET:如果进程有足够的权限,把共享内存当前关联值设置为shmid_ds中的值
IPC_RMID:删除共享内存
第三个参数 struct shmid_ds *buf
是一个指针,指向一个结构。
struct shmid_ds结构体至少有如下成员
struct shmid_ds {
uid_t shm_perm.uid;
uid_t shm_perm.gid;
mode_t shm_perm.mode;
}
返回值
成功返回0 失败返回-1