共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。
共享内存的数据结构
共享内存相关函数
- int shmget(key_t key,size_t size,int shmflg>;用来创建共享内存
- void *shmat(int shmid, const void *shmaddr, int shmflg);将共享内存段连接到进程地址空间
- int shmdt(const void *shmaddr); 将共享内存段与当前进程脱离
- int shmctl(int shmid,int cmd,struct shmid_ds *buf); 用于控制共享内存
参数含义
key | 共享内存段名字 |
---|---|
size | 共享内存大小 |
shmflg | 由九个权限标志构成,它们的用法和创建文件时使用的mode标志是一样的 |
shmid | :共享内存标识 |
shmadder | 指定连接的地址 |
cmd | 将要采取的动作 |
buf | 指向一个保存着共享内存的模式状态和访问权限的数据结构 |
接下来,我们利用上面的函数实现一个client/server通信的例子
Makefile
.PHONY:all
all:client server
client:client.c comm.c
gcc -o $@ $^
server:server.c comm.c
gcc -o $@ $^
.PHONY:clean
rm -f client server
comm.h
1 #ifndef _COMM_H__
2 #define _COMM_H__
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <sys/types.h>
8 #include <sys/ipc.h>
9 #include <sys/shm.h>
10
11 int CreatShm(int size);
12 int DestroyShm(int shmid);
13 int GetShm(int size);
14
15 #endif
comm.c
1 #include "comm.h"
2
3 static int Shm(int size,int flag)
4 {
5 key_t key=ftok("." ,0x6666);
6 if(key<0)
7 {
8 perror(" ftok" );
9 return -1;
10 }
11 int shmid=shmget(key,size,flag);
12 if(shmid<0)
13 {
14 perror("shmget" );
15 return -2;
16 }
17 return shmid;
18 }
19 int CreatShm(int size)
20 {
21 return Shm(size,IPC_CREAT|IPC_EXCL|0666);
22 }
23 int GetShm(int size)
24 {
25 return Shm(size,IPC_CREAT);
26 }
27 int Destroy(int shmid)
28 {
29 if(shmctl(shmid,IPC_RMID,NULL)<0)
30 {
31 perror("shmctl" );
32 return -1;
33 }
34 return 0;
35 }
server.c
1 #include "comm.h"
2
3 int main()
4 {
5 int shmid=CreatShm(1024);
6 char* msg=shmat(shmid,NULL,0);
7 sleep(2);
8 int i=0;
9 while(i++<15)
10 {
11 printf("client#%s\n" ,msg);
12 sleep(1);
13 }
14 shmdt(msg);
15 sleep(2);
16 Destroy(shmid);
17 return 0;
18 }
client.c
1 #include "comm.h"
2
3 int main()
4 {
5 int shmid=GetShm(1024);
6 sleep(1);
7 char* msg=shmat(shmid,NULL,0);
8 sleep(2);
9 int i=0;
10 while(i<15)
11 {
12 msg[i]='A'+i;
13 i++;
14 msg[i]=0;
15 sleep(1);
16 }
17 shmdt(msg);
18 sleep(2);
19 return 0;
20 }