基础知识
共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是 Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。
代码实现
//shm.h 1 #ifndef __SHM__ 2 #define __SHM__ 3 4 #include<stdio.h> 5 #include<sys/ipc.h> 6 #include<sys/shm.h> 7 #include<sys/types.h> 8 9 #define PATH "." 10 #define PROJ_ID 110 11 #define SIZE 4096 //4K 12 13 static int comm_shm(int flag); 14 int create_shm(); 15 int get_shm(); 16 void* at_shm(int shm_id); 17 int dt_shm(void* buf); 18 int destroy_shm(int shm_id); 19 20 #endif //shm.c 1 #include "shm.h" 2 3 static int comm_shm(int flag) 4 { 5 key_t _key=ftok(PATH,PROJ_ID); 6 if(_key<0) 7 { 8 perror("ftok"); 9 return -1; 10 } 11 int shm_id=shmget(_key,SIZE,flag); 12 if(shm_id<0) 13 { 14 perror("shmget"); 15 return -1; 16 } 17 return shm_id; 18 } 19 int create_shm() 20 { 21 return comm_shm(IPC_CREAT|IPC_EXCL); 22 } 23 int get_shm() 24 { 25 return comm_shm(IPC_CREAT); 26 } 27 void* at_shm(int shm_id) 28 { 29 void* buf=shmat(shm_id,NULL,0); 30 if(buf==(void*)-1) 31 { 32 perror("shmat"); 33 return (void*) -1; 34 } 35 else 36 return buf; 37 } 38 int dt_shm(void* buf) 39 { 40 int ret=shmdt(buf); 41 if(ret==-1) 42 { 43 perror("shmdt"); 44 return -1; 45 } 46 else 47 return 0; 48 } 49 int destroy_shm(int shm_id) 50 { 51 int ret=shmctl(shm_id,IPC_RMID,NULL); 52 if(ret==-1) 53 { 54 perror("shmctl"); 55 return -1; 56 } 57 else 58 return 0; 59 } //client.c 1 #include "shm.h" 2 3 int main() 4 { 5 int shmid=create_shm(); 6 char* buf= at_shm(shmid); 7 int i=0; 8 for(;i<SIZE;i++) 9 { 10 sleep(3); 11 buf[i]=‘A‘; 12 buf[i+1]=‘\0‘; 13 } 14 dt_shm(buf); 15 destroy_shm(shmid); 16 return 0; 17 } //server.c 1 #include "shm.h" 2 3 int main() 4 { 5 int shmid=get_shm(); 6 char* buf= at_shm(shmid); 7 int i=0; 8 for(;i<SIZE;i++) 9 { 10 sleep(3); 11 printf("%s\n",buf); 12 } 13 dt_shm(buf); 14 return 0; 15 } //makefile 1 .PHONY:all 2 all:client server 3 client:client.c shm.c 4 gcc -o $@ $^ 5 server:server.c shm.c 6 gcc -o $@ $^ 7 .PHONY:clean 8 clean: 9 rm -f client server
输出结果:
结果分析:
client和server实现了访问同一块内存空间
3. 相关函数
1)创建
shmget
函数中参数
key:用来变换成一个标识符,而且每一个IPC对象与一个key相对应。
size:为当新建一个共享内存段时,请求的内存长度(以字节为单位)。
注意:内核是以页(4K)为单位分配内存,当size参数的值不是系统内存页长的整数倍时,系统会分配给进程最小的可以满足size长的页数,但是最后一页的剩余部分内存是不可用的。当打开一个内存段时,参数size的值为0。
flag:中的相应权限位初始化ipc_perm结构体中的mode域。同时参数flag是函数行为参数,它指定一些当函数遇到阻塞或其他情况时应做出的反应。
2)挂接,去关联
shmat,shmdt
3)清理
shmctl
本文出自 “sunshine225” 博客,请务必保留此出处http://10707460.blog.51cto.com/10697460/1765197
原文地址:http://10707460.blog.51cto.com/10697460/1765197