alin的学习之路:共享内存Linux下的API

共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。

  1. 共享内存使用流程

    1. 向内核申请一块内存 -> 指定大小
    2. 如果有两个进程, 需要通信, 可以使用这块共享内存来完成, 先创建出这两个进程
    	- 进程A
    	- 进程B
    3. 进程A和进程B分别和共享内存进行关联
    	- 拿到共享内存的地址 -> 首地址
    4. 两个进程可以通过这个首地址对共享内存进行读/写操作
    5. 如果这个进程不再使用这块共享内存, 需要和共享内存断开关联
    	- 进程退出, 对共享内存是没有任何影响的
    6. 当不再使用共享内存的时候, 需要将共享内存销毁
    
  2. 共享内存头文件

    #include <sys/ipc.h>
    #include <sys/shm.h>
    
  3. 共享内存操作函数

    • 创建或打开一块共享内存区

      // 创建共享内存
      // 共享内存已经存在, 打开共享内存
      // 可以创建多块共享内存
      int shmget(key_t key, size_t size, int shmflg);
      	参数:
      		- key: 通过这个key记录共享内存在内核中的位置, 需要是一个>0的整数, ==0不行
      			随便指定一个数就可以, 后边会介绍一个函数ftok
      		- size: 创建共享内存的时候, 指定共享内存的大小
      			- 如果是打开一个已经存在的共享内存, size写0就可以
      		- shmflg: 创建共享内存的时候使用, 类似于open函数的flag
      			- IPC_CREAT: 创建共享内存
      				- 创建的时候需要给共享内存一个操作权限
      					- IPC_CREAT | 0664
      			- IPC_CREAT | IPC_EXCL: 检测共享内存是否存在
      				- 如果存在函数返回-1
                      - 不存在, 返回0
      	返回值:
      		成功: 创建/打开成功, 得到一个整形数 -> 对应这块共享内存
      		失败: -1
      // 应用
      // 1. 创建共享内存
      int shmid = shmget(100, 4096,  IPC_CREAT | 0664);
      int shmid = shmget(200, 4096,  IPC_CREAT | 0664);
      // 2. 打开共享内存
      int shmid = shmget(100, 0, 0);  
      
    • 将当前进程和共享内存关联到一起

      // 进程和共享内存产生关系
      void *shmat(int shmid, const void *shmaddr, int shmflg);
      	参数:
      		- shmid: 通过这个参数访问共享内存, shmget()函数的返回值
      		- shmaddr: 指定共享内存在内核中的位置,NULL -> 委托内核区指定
      		- shmflg: 关联成功之后对共享内存的操作权限
      			- SHM_RDONLY: 只读
      			- 0: 读写
      	返回值:
      		成功: 共享内存的地址 (起始地址)
              失败:  (void *) -1
      // 函数调用:
      void* ptr = shmat(shmid, NULL, 0);
      // 写内存
      memcpy(ptr, "xxxx", len);
      // 读内存
      printf("%s", (char*)prt);
      
    • 将共享内存和当前进程分离

      // 进程和共享内存分离 -> 二者就没有关系了
      int shmdt(const void *shmaddr);
      	参数: 共享内存的起始地址, shmat()返回值
      	返回值:
      		- 成功: 0
              - 失败: -1
      
    • 共享内存操作 -( 删除共享内存 )

      // fcntl
      // setsockopt
      // getsockopt
      // 对共享内存进程操作
      int shmctl(int shmid, int cmd, struct shmid_ds *buf);
      	参数: 
      		- shmid: 通过这个参数访问共享内存, shmget()函数的返回值
      		- cmd: 对共享内存的操作
      			- IPC_STAT: 获取共享内存的状态
      			- IPC_SET: 设置共享内存状态
      			- IPC_RMID: 标记共享内存要被销毁
      		- buf: 为第二个参数服务的
      			cmd==IPC_STAT: 获取共享内存具体状态信息
      			cmd==IPC_SET: 自定义共享内存状态, 设置到内核的共享内存中
      			cmd==IPC_RMID: 这个参数没有用了, 指定为NULL
      	返回值:
      		成功: 0
              失败: -1
      // 删除共享内存
      shmctl(shmid, IPC_RMID, NULL);
      
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐