进程间通信(共享内存)

共享内存



一、共享内存

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

在这里插入图片描述

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.声明周期随内核;
注意事项: 各个进程对共享内存的操作都是不安全的操作
  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李憨憨_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值