(Fastest IPC)共享内存

本片博客会粘贴部分代码,想要了解更多代码信息,可访问小编的GitHub关于本篇的代码
这里有涉及的mmap的知识
下图为共享内存原理图
在这里插入图片描述

因为共享内存是直接将申请来的一块物理内存映射到虚拟地址空间中,允许两个或多个进程共享,因此进行数据传输的时候相较于其它进程间通信方式,少了两步用户态与内核态数据拷贝的过程,因此共享内存是最快的进程间通信方式。
  • 创建共享内存
int shmget(key_t key, size_t size, int shmflg);

key: 操作系统上ipc标识
size: 要创建的共享内存大小
shmflg:
IPC_CREAT|IPC_EXCL|0664
返回值:操作句柄 失败:-1

  • 内存映射
void *shmat(int shmid, const void *shmaddr, int shmflg);

shmid: 操作句柄
shmaddr: 映射起始地址,NULL(操作系统分配)
shmflg: SHM_RDONLY–只读 否则读写
成功返回:映射的虚拟地址空间首地址
失败返回:(void*)-1

  • 解除映射
int shmdt(const void *shmaddr);

shmaddr 共享内存的映射首地址
返回值:成功:0 失败:-1

  • 删除共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

shmid: 句柄
cmd: IPC_RMID 删除
buf: 用于接收共享内存描述信息,不关心可以置空

操作系统:如果有进程依然与共享内存保持映射连接关系,那么共享内存将不会被立即删除,而是等最后一个映射断开后删除 ,在这期间,将拒绝其他进程映射。

服务端
/*这是共享内存的服务端,目的是:往共享内存写入数据后*/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
//定义一个ipc标识符
#define KEY 0x520

int main()
{
    umask(0);
    //创建共享内存
    //int shmget(key_t key, size_t size, int shmflg);
    int shmid=-1;
    shmid=shmget(KEY,520,IPC_CREAT|0664);
    if(shmid<0){
        perror("shmget error");
        return -1;
    }else
    {
        //映射到虚拟地址空间
        //void *shmat(int shmid, const void *shmaddr, int shmflg);
        void*shmhead=shmat(shmid,NULL,0);//shmaddr是要映射的起始地址,NULL表示由系统分配,
        //shmflg如果是SHM_RDONLY则只读权限,否则读写
        if(shmhead==(void*)-1)
        {
            perror("shmat error");
            return -1;
        }
        while(1)
        {
            //映射成功,写操作
            memset(shmhead,0x00,520);
            scanf("%s",(char*)shmhead);
            sleep(1);
        }
        //解除映射int shmdt(const void *shmaddr);
        shmdt(shmhead);
        //删除共享内存int shmctl(int shmid, int cmd, struct shmid_ds *buf);
        shmctl(shmid,IPC_RMID,NULL);
    }
    return 0;
}
客户端
/*这是共享内存的客户端,目的:隔一秒钟,去共享内存取一次数据*/
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
//定义一个ipc标识符
#define KEY 0x520

int main()
{
    umask(0);
    //创建共享内存
    //int shmget(key_t key, size_t size, int shmflg);
    int shmid=shmget(KEY,520,IPC_CREAT|0664);
    if(shmid<0){
        perror("shmget error");
        return -1;
    }else
    {
        //映射到虚拟地址空间
        //void *shmat(int shmid, const void *shmaddr, int shmflg);
        void*shmhead=shmat(shmid,NULL,SHM_RDONLY);//shmaddr是要映射的起始地址,NULL表示由系统分配,
        //shmflg如果是SHM_RDONLY则只读权限,否则读写
        if(shmhead==(void*)-1)
        {
            perror("shmat error");
            return -1;
        }
        while(1)
        {
            //映射成功,读取数据
            printf("memshare:%s\n",(char*)shmhead);
            sleep(1);
        }
        //解除映射int shmdt(const void *shmaddr);
        shmdt(shmhead);
        //删除共享内存int shmctl(int shmid, int cmd, struct shmid_ds *buf);
        shmctl(shmid,IPC_RMID,NULL);
    }
    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值