Linux_进程间通信_3)共享内存

一.优点

         共享内存是最快的IPC

二.本质

         同一个物理内存同时映射到不同进程的虚拟地址空间中,共享内存其实是效率最高的通信方式,访问共享内存和访问其他内存没有什么区别。

三.特性

   1)可用于任何进程之间

   2)双向通信,全双工

   3)没有内置同步互斥机制

   4)支持随机访问

   5)没有内置同步互斥机制

   6)声明周期随内核

扫描二维码关注公众号,回复: 2382753 查看本文章

四.API

1.创建和打开共享内存

   1)头文件:      #include <sys/ipc.h>
                               #include <sys/shm.h>

   2)函数原型:int shmget(key_t key, size_t size, int shmflg);

   3)函数参数:key 共享内存的名字  size 共享内存的大小  shmflg 由九个权限标志构成,用法和创建文件时的mode一样

   4)返回值:成功返回共享内存的标识码,失败返回-1

   5)特点:内存只分配4k的倍数,小于4k按4k分配

2.将共享内存挂载到进程的地址空间

  1)头文件:#include <sys/types.h>
                        #include <sys/shm.h>

  2)函数原型:void *shmat(int shmid, const void *shmaddr, int shmflg);

  3)函数参数:shmid 共享内存标识码  shmaddr 指定连接的地址(为NULL操作系统自己选择)

                            shmflg 两个值SHM_RND和SHM_RDONLY

 4)返回值:成功返回挂载到虚拟空间起始地址的指针,失败返回-1

 5)说明:shmaddr不为空,shmflg无SHM_RND标记,则以shmaddr为连接地址

                   shmaddr不为空,shmflg有SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍

                   shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

3.将共享内存与当前进程脱离

 1)头文件:#include <sys/types.h>
                       #include <sys/shm.h>

 2)函数原型:int shmdt(const void *shmaddr);

 3)参数:shmaddr:由shmat所返回的指针

 4)返回值:成功返回0,失败返回-1

 5)注意:脱离只是从进程上卸载,并不等于删除共享内存

4.控制共享内存

 1)头文件:#include <sys/ipc.h>
                       #include <sys/shm.h>

 2)函数原型:int shmctl(int shmid, int cmd, struct shmid_ds *buf);

 3)函数参数:shmid 共享内存标识码  cmd 将要采取的动作  buf 指向一个保存着共享内存的模式状态和访问权限的数据结构

 4)返回值:成功返回0,失败返回-1

 5)说明:cmd的三种情况   IPC_STAT把shmid_ds结构中的数据设置为共享内存的当前关联值

                                               IPC_SET 在进程有足够权限的前提下,把共享内存的当前关联值设置为shmid_ds数据结构中给出的值

                                               IPC_RMID删除共享内存段

五.撸一段代码

sever

  1 #include <stdio.h>
  2 #include <sys/ipc.h>
  3 #include <sys/shm.h>
  4 #include <sys/types.h>
  5 
  6 int main(void){
  7     key_t key=ftok(".",0x001);
  8     int shm=shmget(key,4096,IPC_CREAT|0644);
  9     if(shm<0){
 10         perror("shmget");
 11         return 1;
 12     }
 13 
 14     char* point=shmat(shm,NULL,0);
 15     if(point==NULL){
 16         perror("shmat");
 17         return 1;
 18     }
 19     while(1){
 20         printf("me say:");
 21         fflush(stdout);
 22         scanf("%s",point);
 23         if(strcmp(point,"exit")==0){
 24                 break;
 25         }
 26         
 27         printf("Other say:");
 28         fflush(stdout);
 29         sleep(3);
 30         printf("%s\n",point);
 31     }
 32     shmctl(shm,IPC_RMID,0);
 33     return 0;
 34 
 35 }                      

client

  1 #include <stdio.h>
  2 #include <sys/ipc.h>
  3 #include <sys/shm.h>
  4 #include <sys/types.h>
  5 
  6 int main(void){
  7     int key=ftok(".",0x001);
  8     int shm=shmget(key,4096,0);
  9     if(shm<0) perror("shmget"),exit(1);
 10 
 11     char * buf;
 12     buf=shmat(shm,NULL,0);
 13     if(*buf==-1){
 14         perror("shmat");
 15         return 1;
 16     }
 17     while(1){
 18         printf("Other say#");
 19         fflush(stdout);
 20         sleep(3);
 21         printf("%s\n",buf);
 22         buf=NULL;
 23         printf("me say:");
 24         fflush(stdout);
 25         scanf("%s",buf);
 26     }
 27     return 0;
 28 }

总结:由于共享内存没有同步互斥机制,在两方操作难度很大,很难进行互斥操作,在以后信号量的地方我会继续改进。

猜你喜欢

转载自blog.csdn.net/warrior_harlan/article/details/81129533
今日推荐