美文网首页Android开发
System V IPC:共享内存

System V IPC:共享内存

作者: FakeCSer爱去网吧 | 来源:发表于2020-02-20 20:49 被阅读0次

    共享内存原理

    特点
    • 相比管道通信,在读写数据的时候不用切内核态,使通信效率提升
    • 相比命名管道,命名管道是内核管理的缓冲区队列,而共享内存不是队列结构
    • 属于System V IPC(另外两种是信号量消息队列
    • 一种IPC资源,不依赖进程是否存在
    原理
    • 进程共享使用同一段物理内存
    • 具有使用权限的进程将共享内存(同一块物理内存)映射到自己地址空间(虚拟地址空间)的一部分
    • 每个共享内存有一个 shmid_ds类型的结构与之对应
    struct shmid_ds
    {
      uid_t shm_perm.uid;
      uid_t shm_perm.gid;
      mode_t shm_perm.mode;
      
    ...
    }
    

    使用到的API

    • 创建(打开)共享内存--shmget
    #include <sys/shm.h>
    int shmget(key_t key,size_t size,int shmflg);
    

    参数表
    key:共享内存对应键值
    size:共享内存大小
    shmflg:共享内存权限----IPC_CREATE(创建shm,省略则为打开)|mode(0777)
    返回值
    大于0:共享内存ID
    -1 :出错

    • 连接共享内存--shmat
    #include <sys/shm.h>
    void * shmat(int shmid,void * shmaddr,int flg);
    

    参数表
    shmid:共享内存id号(shmget返回值)
    shmaddr:共享内存的起始地址(常用NULL,让内核给分配)
    flg:访问共享内存的方式:SHM_RDONLY(读方式)/ 0(可读可写)
    返回值
    大于0:共享内存起始地址
    -1 :出错

    • 解脱共享内存--shmdt
      解脱后shmid_ds结构体中计数器减一(类似文件操作)
    #include <sys/shm.h>
    int shmdt(void * shmaddr);
    

    参数表
    shmaddr:共享内存起始地址(shmat返回值)
    返回值
    0:成功
    -1 :出错

    • 操作(删除)共享内存--shmctl
    #include <sys/shm.h>
    int shmctl(int shmid,int cmd,struct shmid_ds *buf);
    

    参数表
    shmid:共享内存id号
    cmd:执行的操作:如 IPC_RMID,删除共享内存
    buf:cmd不同,buf不同,删除时填NULL
    返回值
    0:成功
    -1 :出错

    示例代码

    写端

      1 #include <sys/shm.h>
      2 #include <unistd.h> //sleep
      3 #include <string.h> //strcpy
      4 #include <iostream> //perror
      5 using namespace std;
      6 #define SHM_KEY 98  //设定创建共享内存的键值
      7 
      8 int main()
      9 {
     10         int seg_id;     //共享内存id号
     11         char *mem_ptr = NULL;   //指向共享内存的指针
     12         
     13         seg_id = shmget(SHM_KEY,1024,IPC_CREAT|0777);//创建共享内存:键值,大小,权限
     14         if( seg_id == -1 )
     15         {
     16                 perror( "shmget" );
     17                 exit(EXIT_FAILURE);     
     18         }
     19         
     20 
     21         mem_ptr = (char*)shmat(seg_id,NULL,0);//连接共享内存
     22         if(mem_ptr == NULL)
     23         {
     24                 perror("shmat");
     25                 exit(EXIT_FAILURE);     
     26         }
     27         
     28         
     29         cout << "1" << endl;
     30         char  temp[8] = "1234567";
     31         strcpy(mem_ptr,"1234567\n");
     32 //      cout << sizeof(*mem_ptr) << endl;
     33         cout << "2" << endl;
     34         sleep(10);      //等待读端读数据
     35 
     36         shmctl(seg_id,IPC_RMID,NULL);//删除共享内存
     37         return 0;
     38 } 
    

    读端

      1 #include <sys/shm.h> 
      2 #include <unistd.h> 
      3 #include <string.h> 
      4 #include <iostream>
      5 using namespace std;
      6 
      7 #define SHM_KEY 98
      8 
      9 int main()
     10 {
     11         int seg_id;
     12         
     13         char * mem_ptr;
     14         seg_id = shmget(SHM_KEY,00,0777);
     15         if( seg_id == -1 )
     16         {       
     17                 perror("shmget");
     18                 exit(EXIT_FAILURE);     
     19         }
     20 
     21 
     22         mem_ptr = (char*)shmat(seg_id,NULL,0);
     23         if(mem_ptr == NULL)
     24         {       
     25                 perror("shmat");
     26                 exit(EXIT_FAILURE);     
     27         }
     28         cout << mem_ptr <<endl;
     29 
     30         shmdt(mem_ptr);//共享内存解脱
     31         return 0;       
     32 } 
    

    相关文章

      网友评论

        本文标题:System V IPC:共享内存

        本文链接:https://www.haomeiwen.com/subject/sxdfqhtx.html