一、概念
共享内存:允许两个不相关的进程访问同一个逻辑内存,不同进程之间共享的内存通常为同一段物理内存。
进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址。如果某个进程向共享内存写入数据,所做的改动将立即回影响到可以访问同一段共享内存的其他进程。
二、共享内存的特点
·共享内存是所有进程间通信最快的(直接是用户到用户)
·不带互斥与同步机制
·生命周期随内核
三、函数
1、shmget函数
功能:用来创建共享内存
原型:
参数:key——这个共享内存段的名字
size——共享内存的大小
shmflg——由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回该共享内存的标识码,失败返回-1
2、shmat函数(关联共享内存(映射))
功能:将共享内存段连接到进程地址空间
原型:
参数:shmid——共享内存的标识
shmaddr——指定连接的地址
shmflg——它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回指向共享内存第一个节的指针,失败返回-1
说明:
shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址自动向下调整为SHMLBA的整数倍。公式:shmaddr - (shmaddr % SHMLBA)
shmflg = SHM_RDONLY:表示连接操作作用来只读共享内存
3、shmdt函数(取消关联(解映射))
功能:将共享内存段与当前进程脱离
原型:
参数:shmaddr——由shmat所返回的指针
返回值:成功返回0,失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段
4、shmctl函数
功能:用于控制内存
原型:
参数:shmid——由shget返回的共享内存标识码
cmd——将要采取的动作(有三个可取值)
buf——指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0,失败返回-1
Makefile
1 .PHONY:all
2 all:server client
3
4 client:client.c comm.c
5 gcc -o $@ $^
6 server:server.c comm.c
7 gcc -o $@ $^
8
9 .PHONY:clean
10 clean:
11 rm -f client server
comm.h
1 #ifndef _COMM_H_
2 #define _COMM_H_
3
4 #include<stdio.h>
5 #include<sys/types.h>
6 #include<sys/ipc.h>
7 #include<sys/shm.h>
8 #include<stdlib.h>
9 #include<unistd.h>
10
11 //#define PATHNAME "."
12 //#define PROJ_ID 0x6666
13
14 int createshm(int size);
15 int destroyshm(int shmid);
16 int getshm(int size);
17 #endif
comm.c
1 #include "comm.h"
2
3 static int commshm(int size,int flags)
4 {
5 key_t _key = ftok(".",0x6666);
6 if(_key < 0){
7 perror("ftok");
8 return -1;
9 }
10
11 int shmid = shmget(_key,size,flags);
12 if(shmid < 0){
13 perror("shmget");
14 return -2;
15 }
16 return shmid;
17 }
18
19 int destroyshm(int shmid)
20 {
21 if(shmctl(shmid,IPC_RMID,NULL) < 0){
22 perror("shmctl");
23 return -1;
24 }
25 return 0;
26 }
27
28 int createshm(int size)
29 {
30 return commshm(size,IPC_CREAT|IPC_EXCL|0666);
31 }
32
33 int getshm(int size)
34 {
35 return commshm(size,IPC_CREAT);
36 }
server.c
1 #include "comm.h"
2
3 int main()
4 {
5 int shmid = createshm(1024);
6 printf("create shm success\n");
7
8 char *addr = shmat(shmid,NULL,0);
9 sleep(2);
10 int i = 0;
11 while(i++ < 26){
12 printf("client:> %s\n",addr);
13 sleep(1);
14 }
15 shmdt(addr);
16 sleep(2);
17 destroyshm(shmid);
18 return 0;
19 }
client.c
1 #include "comm.h"
2
3 int main()
4 {
5 int shmid = getshm(1024);
6 sleep(1);
7 char *addr = shmat(shmid,NULL,0);
8 sleep(2);
9 int i = 0;
10 while(i < 26){
11 addr[i] = 'A' + i;
12 i++;
13 addr[i] = 0;
14 sleep(1);
15 }
16 shmdt(addr);
17 return 0;
18 }
查看共享内存
删除共享内存(不是必须手动删除)