内存共享
内存共享,它也是一种进程间通信的方式,它是在虚拟地址空间中堆和栈地址空间的中间的共享映射区中开辟一块地址,然后由页表和mmu在物理内存中开辟一段空间,其他进程如果获取到了这个内存的ID便可以和另外的进程共享这段内存。
内存共享的特点:高效,它比其他的进程间通信的方式都要高效因为它直接看到的就是相当于他自己的一块内存。
要用到的函数:
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);//控制共享内存
shmat它是用来将物理内存映射到自己的地址空间的一个函数,返回值为需要接受的指针,如果要指定映射到当前进程的哪一段内存可以用shmaddr,如果设置了shmaddr则必须将shmflg指定为SHM_RND,shmlag还可以设置为SHM_RDONLY,只读形式。
shmdt用来接触映射关系
shmctl用于控制内存,和前面说过的类似。
下面是用内存共享完成的一个写入消息和读取消息的小程序
结果如下图:
comm.c
1 #include"comm.h" 2 static int comm_get_shm(int shm_size,int flag) 3 { 4 key_t shm_key=ftok(_PATH_,_PROJ_ID_); 5 if(shm_key<0) 6 { 7 perror("ftok"); 8 return -1; 9 } 10 int shm_id=shmget(shm_key,shm_size,flag); 11 if(shm_id<0) 12 { 13 perror("shmget"); 14 } 15 return shm_id; 16 } 17 18 int creat_shm(int shm_size) 19 { 20 umask(0); 21 return comm_get_shm(shm_size,IPC_CREAT|IPC_EXCL|0666); 22 } 23 int get_shm() 24 { 25 return comm_get_shm(1,IPC_CREAT); 26 } 27 28 void *at_shm(int shm_id) 29 { 30 return shmat(shm_id,NULL,0); 31 } 32 int delete_shm(void *addr) 33 { 34 return shmdt(addr); 35 } 36 int distroy_shm(int shm_id) 37 { 38 return shmctl(shm_id,IPC_RMID,NULL); 39 }
server.c
1 #include"comm.h" 2 3 4 int main() 5 { 6 int shm_id=creat_shm(4096); 7 char *server=at_shm(shm_id); 8 while(1) 9 { 10 printf("%s\n",server); 11 sleep(1); 12 } 13 distroy_shm(shm_id); 14 return 0; 15 }
client.c
1 2 #include"comm.h" 3 4 5 int main() 6 { 7 int shm_id=get_shm(); 8 char *client=at_shm(shm_id); 9 int i=0; 10 while(i>=0) 11 { 12 client[i]=‘w‘; 13 client[i+1]=‘\0‘; 14 i++; 15 sleep(1); 16 } 17 return 0; 18 }
内存共享是最高效的一种进程间通信的方法,它省去了从用户到内存的复制和从内存到用户的复制,但是它的同步于互斥机制需要用户手动的去实现,总之内存共享给程序员自由发挥的空间更大。
本文出自 “痕迹” 博客,请务必保留此出处http://wpfbcr.blog.51cto.com/10696766/1764669
原文地址:http://wpfbcr.blog.51cto.com/10696766/1764669