进程间通信(共享内存)

Posted 李憨憨_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程间通信(共享内存)相关的知识,希望对你有一定的参考价值。

共享内存



一、共享内存

  共享内存 : 用于进程间的数据共享

在这里插入图片描述

1.共享内存实现通信的原理

开辟一块物理内存空间, 各个进程将同一块物理内存空间映射到自己的虚拟地址空间中, 通过虚拟地址进行访问, 进而实现数据共享
  共享内存是最快的进程间通信方式, 因为通过虚拟地址空间映射后, 直接通过虚拟地址访问物理内存, 相较于其他方式少了两步数据拷贝的操作.

2.操作流程

1.创建或打开共享内存
int shmget(key_t key, size_t size, int shmflg);

在这里插入图片描述



 key: 标识符- -通过相同的标识符, 多个进程就可以打开同一块共享内存;

 size: 要创建的共享内存大小;

 shmflg: 打开方式 + 权限;  IPC_CREAT: 不存在则创建, 存在则打开;
             IPC_EXCL与IPC_CREAT搭配使用, 文件存在则报错, 不存在则创建打开;

 返回值: 成功返回非负整数–操作句柄; 失败返回-1;

2.与进程建立映射关系
void *shmat(int shmid, const void *shmaddr, int shmflg);

在这里插入图片描述



 shmid: shmget返回的操作句柄;

 shmaddr: 映射的首地址, 通常置NULL;

 shflg: SHM_RDONLY-只读;  0-可读可写;

 返回值: 成功返回映射后的首地址;  失败返回(void*)-1;

3.对共享内存进行内存操作
 凡是涉及到内存操作的接口, 都能对共享内存进行操作;memcpy, strcpy, printf......
4.与进程间解除映射关系
int shmdt(const void *shmaddr);


 shmaddr: shmat返回的映射首地址;
 返回值: 成功返回0; 失败返回-1;


5.删除共享内存

int shmctl(int shmid, int cmd, struct shmid_ds *buf);

在这里插入图片描述


 shmid: shmget返回的操作句柄;
 cmd: 要对共享内存进行的操作类型;
   IPC_CMD: 标记要删除的共享内存段;
    映射连接数为0时删除共享内存; 禁止新的映射连接

 buf: 用于获取或设置共享内存属性的, 简单使用置NULL即可;
 返回值: 成功返回0; 失败返回-1;

二、代码实践

1.创建共享内存

代码如下(示例):

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <sys/shm.h>
  5 #define IPC_KEY 0x01234567
  6 #define PROJ_ID 0x01234567
  7 int main()
  8 {
  9     //key_t key = ftok("./", PROJ_ID);
 10     //shmget(标识符, 大小, 打开方式和权限)
 11     int shmid = shmget(IPC_KEY, 32, IPC_CREAT | 0664);
 12     if(shmid < 0){
 13         perror("shmget error");
 14         return -1;
 15     }
 16     return 0;
 17 }

在这里插入图片描述

ipcs: 查看系统内核当中所有的进程间通信资源; ipcs -m: 查看共享内存; ipcs -q: 查看消息队列;ipcs -s: 查看信号量;

2.映射到虚拟地址

代码如下(示例):

 16     //shmat(句柄, 映射首地址, 访问方式)
 17     void *shm_start = shmat(shmid, NULL, 0);
 18     if(shm_strat == (void*)-1){
 19         perror("shmat error");
 20         return -1;
 21     }
 22     while(1){
 23         printf("%s\\n", (char*)shm_start);
 24         sleep(1);
 25     }
 26     shmdt(shm_start);
 27     //shmctl(句柄, 操作类型, 信息结构)
 28     shmctl(shmid, IPC_RMID, NULL);
 29     return 0;
 30 }

在这里插入图片描述

3.修改共享内存(一个写, 一个读)

在这里插入图片描述


关闭read, write仍然一直在修改, 关闭write, read也一直在读, 两边互不影响
两边同时打开, 映射连接数为2;在这里插入图片描述
在这里插入图片描述

总结

共享内存:
 通信原理: 开辟一块物理内存, 多个进程将同一块内存映射到自己的虚拟地址空间, 进行访问, 进而实现数据共享.
 特性:
  1.效率最高的进程间通信方式;
  2.声明周期随内核;
注意事项: 各个进程对共享内存的操作都是不安全的操作

以上是关于进程间通信(共享内存)的主要内容,如果未能解决你的问题,请参考以下文章

进程间通信

操作系统实验3共享内存进程间通信实验

linux进程间通信之Posix共享内存用法详解及代码举例

进程间通信之共享内存

进程间通信

进程间通信