共享内存
共享内存是被多个进程共享的一部分物理内存。一个进程向共享内存写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
如下图所示,共享内存的地址在进程A
中的地址可能是0x5000
,在进程B
中的地址可能是0x7000
,这是因为共享内存映射到不同进程当中的不同位置。
共享内存的实现分为2
个步骤:
- 使用
shmget
函数创建共享内存。 - 使用
shmat
函数将创建的共享内存映射到具体的进程空间。
创建共享内存
创建共享内存使用函数shmget
:
int shmget ( key_t key, int size, int shmflg );
key
是标识共享内存的键值,可以取非负整数
或IPC_PRIVATE
。
- 当
key
是IPC_PRIVATE
时,shmflg
不需要IPC_CREAT
。 - 当
key
是非负整数
时,shmflg
需要IPC_CREAT
。
size
是共享内存的大小,以字节为单位。shmflg
是权限标志,与文件的读写权限一样。
如果函数执行成功,则返回共享内存标识符,否则返回-1
。
映射共享内存
映射共享内存使用函数shmat
:
int shmat ( int shmid, char *shmaddr, int flag );
shmid
:shmget
函数返回的共享内存标识符。shmaddr
:通常为0
。flag
:通常为0
。
如果函数执行成功,则返回共享内存映射到进程中的地址,否则返回-1
。
删除共享内存
当一个进程不再需要共享内存时,需要把它从进程地址空间中删除:
int shmdt ( char *shmaddr );
参数shmaddr
是从shmat
中获得的。
父子进程共享内存
代码实例:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define PERM (S_IRUSR | S_IWUSR)
int main ( int argc, char **argv ) {
int shmid;
char *p_addr, *c_addr;
if ( argc != 2 ) {
fprintf ( stderr, "Usage: %s\n", argv[0] );
exit ( 1 );
}
if ( ( shmid