1. 共享内存 是被多个进程共享的异步分物理内存。
共享内存时进程间共享数据最快的一种方法,一个进程向共享内存区域内写入数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
2. 共享内存的实现,分为两个步骤:
a. 创建共享内存,使用 shmget 函数。
b. 映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用 shmat 函数。
3. 创建共享内存
当key取值为IPC_PRIVATE时,shmget()将会创建一块新的共享内存;
当key取值为0时,而参数shmflg中又设置IPC_PRIVATE这个标志,则同样会创建一块新的共享内存。
返回值:成功返回共享内存标识符,失败返回-1;
4. 共享内存映射
shmid --- shmget()返回的共享内存标识符
shmaddr --- 进程空间中的地址, (shmaddr =0 ,则让系统自动制定一个地址)
flag --- 决定以什么方式来确定映射的地址(通常为0)
返回值: 成功返回共享内存映射到进程中的地址,失败返回-1.
5. 共享内存 解除映射
6. 例 shmem.c
共享内存时进程间共享数据最快的一种方法,一个进程向共享内存区域内写入数据,共享这个内存区域的所有进程就可以立刻看到其中的内容。
2. 共享内存的实现,分为两个步骤:
a. 创建共享内存,使用 shmget 函数。
b. 映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用 shmat 函数。
3. 创建共享内存
int shmget(key_t key, int size, int shmflg);
key --- 标识共享内存的键值:(0/IPC_PRIVATE)
当key取值为IPC_PRIVATE时,shmget()将会创建一块新的共享内存;
当key取值为0时,而参数shmflg中又设置IPC_PRIVATE这个标志,则同样会创建一块新的共享内存。
返回值:成功返回共享内存标识符,失败返回-1;
4. 共享内存映射
int shmat(int shmid, char* shmaddr, int flag)
参数:
shmid --- shmget()返回的共享内存标识符
shmaddr --- 进程空间中的地址, (shmaddr =0 ,则让系统自动制定一个地址)
flag --- 决定以什么方式来确定映射的地址(通常为0)
返回值: 成功返回共享内存映射到进程中的地址,失败返回-1.
5. 共享内存 解除映射
int shmdt(char *shmaddr)
当一个进程不再需要共享内存时,需要把它从进程地址空间中脱离。
6. 例 shmem.c
#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/ipc.h>
#include <sys/shm.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\a", argv[0]);
exit(0);
}
//创建1k的共享内存,可读可写
if((shmid = shmget(IPC_PRIVATE, 1024, PERM)) == -1){
fprintf(stderr, "Create share memory error: %s\n\a",
strerror(errno));
}
//创建子进程
if(fork()){ //父进程,写操作
p_addr = shmat(shmid, 0 , 0); //映射到父进程中
//地址为0,说明让系统自动指定地址
memset(p_addr, '\0', 1024);
strncpy(p_addr, argv[1], 1024); //拷贝命令行输入字符到共享内存
wait(NULL);
exit(0);
} else{
sleep(1); //子进程,读操作
c_addr = shmat(shmid, 0 ,0); //共享内存映射到子进程
printf("Client get %s\n", c_addr);
exit(0);
}
}