[Linux网络编程]环形共享内存的设计

共享队列是一台主机通信的最快方式,它的好处区别于消息队列及其他通信它可以自定义存储结构。在高并发的应用场景中,多个客户端同时发送信息,信息发送的速度远远大于处理速度,所以我们常常设计一个共享内存预先把发送来的信息进行存储。
摘要由CSDN通过智能技术生成

      在上一篇的文章中总结了线程池的设计使用,本篇文章总结了环形共享内存。两者相辅相成,缺一不可,都是为了后面前置后置服务器做铺垫。
      完整的代码文中已经给出,如需整个测试项目,私信发。
目录链接
在这里插入图片描述

2021-09-09复习内容

  • 注意头结构体 和 整体结构体。头结构体作为整体结构体的成员,整体结构体和几个操作共享内存的函数作为类的方法和属性,
  • 头结构体包括:块大小 总块数 读写索引等基本信息
  • 整体结构体包括头部指针 实际负载指针,共享内存的句柄,4个信号量,区别于单个生产者和消费者2个信号量即可,这边还需要多出两个控制多个生产者之间和多个消费者之间的互斥,代码中注释都写的很详细。
  • 类中函数 包含 ShmFifo构造函数初始化 共享内存和信号量,shmfifo_get配和信号量和读索引从格子拷贝数据。shmfifo_put配合信号量和写索引从格子考入数据,还包括销毁和判断的函数。
  • 注意到环形共享队列的好处,可以同时读和写。
  • 注意shmget的第三个参数,如果要创建新的共享内存,需要使用IPC_CREAT,IPC_EXCL,如果是已经存在的,可以使用IPC_CREAT或直接传0,我们常常传入0来判断是否存在了
  • shmat 参数注意

10-03修改内容:

  • 外层读写锁 内层互斥锁 那是不是 可以保存索引 和 索引后移 及时释放互斥锁 再进行拷贝 。这样应该会更快 可以多个生产者 或者消费者一起工作。

1基本介绍

      共享队列是一台主机通信的最快方式,它的好处区别于消息队列及其他通信它可以自定义存储结构。在高并发的应用场景中,多个客户端同时发送信息,信息发送的速度远远大于处理速度,所以我们常常设计一个共享内存预先把发送来的信息进行存储。

2 环形共享内存的设计

2.1 结构图展示

      从下图中我们可以很清楚的看出这个环形共享内存的大致信息,他包含了一个头部的结构体用于存放一些基本的信息(块大小、块总数、读索引、写索引)。后半部分由一块一块相同的信息存储结构构成,用于存放发送来的实际信息。
       0,1,2,3表示块的索引号。以及两个用于实际读写的索引下标。

在这里插入图片描述

2.2 头结构设计

这里是引用

typedef struct shmhead
{
   
    unsigned int blksize;		// 块大小
    unsigned int blocks;		// 总块数
    unsigned int rd_index;		// 读索引
    unsigned int wr_index;		// 写索引
    int total;
}shmhead_t;

2.3 整体结构设计

typedef struct shmfifo
{
   
    shmhead_t *p_shm;			// 共享内存头部指针
    char *p_payload;			// 有效负载的起始地址

    int shmid;					// 共享内存ID 操作的句柄
    int sem_mutex;				// 用来互斥用的信号量 用于同步读的线程(非读和写间)
    int sem_mutex1;				// 用来互斥用的信号量 用于同步写的线程 
    int sem_full;				// 用来控制共享内存是否满的信号量
    int sem_empty;				// 用来控制共享内存是否空的信号量
}shmfifo_t;

2.4 类的设计(声明)

class ShmFifo
{
   
    public:
    	//构造函数用于初始化,申请共享内存空间,挂载映射,信号量的初始化,头结构变量的确定......
        ShmFifo(int key, int blksize,int blocks );

		//数据放入共享内存
        void shmfifo_put(const void *buf);
		//从共享内存取出数据 buf表示的是传出参数
        void shmfifo_get(void *buf);
		//删除共享内存 包括删除信号量 取消映射 释放内存空间
        void shmfifo_destroy();
        int shmfifo_isempty();

    private:
        int key_;//共享内存的键值,是一个整数,可以理解成暗号
        int blksize_;//块的数量
        int blocks_;//块的大小
        shmfifo_t *fifo;//结构体指针

};

2.5 类的定义+注释

      代码总体来说难度不大,配合注释比较容易理解,由于对信号量进行了封装所以可能不习惯。
      一个需要注意的是这边四个信号量的使用,和多个生产者消费者模型是一致的。(比较容易错),可以对比互斥量加条件变量实现方式。
封装的一些函数
int sem_d(int semid)// 删除信号量
int sem_v(int semid)//信号量++
int sem_p(int semid)//信号量-- 为负数阻塞
int sem_create(int semid)//创建信号量
int sem_setval(int semid, int val);//设置信号量的初始值

ShmFifo::ShmFifo(int key, int blksize,int blocks )
        :key_(key),blksize_(blksize),blocks_(blocks)
{
   
        fifo = (shmfifo_t *)malloc(sizeof(shmfifo_t));//共享内存信息的结构体 由于定义为shmfifo_t * fifo指针 所以开辟空间
        /*一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告并且退出*/
        assert
  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Windalove

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

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

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

打赏作者

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

抵扣说明:

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

余额充值