Linux进程通信——使用共享内存

头文件:

#include <sys/ipc.h>

#include <sys/shm.h>

函数:shmget 分配共享内存
函数原型: int shmget(key_t key, size_t size, int shmflg);
key:键值,当为IPC_PRIVATE时新建一块共享内存;若为0时而shmflg中设了IPC_PRIVATE也将新建。
size:内存大小。
shmflg:标志。
IPC_CREAT:内存不存在则新建,否则打开;
IPC_EXCL:只有在内存不存在时才创建,否则出错。
返回:成功则返回标识符,出错返回-1

函数: void shmat(int shmid, char shmaddr, int shmflg);
shmid:通过shmget获取
shmaddr:映射到进程地址空间的起始地址,设为NULL将自动分配
shmflg:标志;SHM-RDONLY为只读,否则可读可写
返回:成功则返回内存起始地址,失败返回-1

函数: int shmdt(const void *shmaddr);
使共享内存区脱离映射的进程的地址空间
返回:成功返回0,错误返回-1

函数: void shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmid:通过shmget获取
cmd:控制命令,如下:
IPC_STAT:获取内存状态
IPC_SET:改变内存状态
IPC_RMID:删除内存
buf:结构体指针,用于存放共享内存状态
返回:成功返回0,错误返回-1

注意:共享内存一旦创建就会一直存在系统中,直到手动删除或者重启系统。
例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**************************************
*
* 使用共享内存进行进程通信
* 龙昌博客:http://www.xefan.com
*
**************************************/
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage:%s str\n", argv[0]);
exit(1);
}
int shmid;
char *p_addr, *c_addr;
//创建共享内存
if ((shmid=shmget(IPC_PRIVATE, 1024, IPC_CREAT)) == -1)
{
perror("shmget");
exit(errno);
}
if(fork() > 0) //父进程向内存写入数据
{
//获取内存起始地址
p_addr = shmat(shmid, 0, 0);
memset(p_addr, 0, 1024);
//向内存中写入数据
strncpy(p_addr, argv[1], 1024);
shmdt(p_addr);
sleep(3);
wait(0);
}
else //子进程从内存中读取数据
{
//获取内存起始地址
c_addr = shmat(shmid, 0, 0);
sleep(4);
printf("child get %s\n", c_addr);
shmdt(c_addr);
}
//删除共享内存
if (shmctl(shmid, IPC_RMID, NULL) < 0)
{
perror("shmctl");
exit(1);
}
return 0;
}