当前位置: 首页 > news >正文

循环队列

循环队列

循环队列(共享内存)笔记

一、为什么共享内存不能使用 STL queue

在多进程共享内存开发中,不能直接使用 STL 的 std::queue,原因如下:

  • STL 容器使用动态内存分配(new/delete),共享内存无法跨进程管理堆内存

  • 依赖移动语义、动态扩容机制,不适合固定内存场景

  • 共享内存中的对象不会调用构造/析构函数,STL 容器无法正常初始化

解决方案:手写固定大小数组循环队列

所有成员变量为普通内置类型,无动态内存,可以直接放入共享内存


二、自定义循环队列整体设计思想

采用 数组 + head + tail + length 计数法实现循环队列:

  • m_head:队头下标(出队位置)

  • m_tail:队尾下标(入队位置)

  • m_length:当前队列元素个数(无需空位置判断)

  • m_data[]:固定大小数组存储数据

  • m_inited:初始化标记(适配共享内存)


三、头文件 _public.h

类声明、函数原型、模板定义

#ifndef __PUBLIC_HH
#define __PUBLIC_HH#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/sem.h>
using namespace std;// 适配共享内存的固定大小循环队列
template <class TT, int MaxLength>
class squeue
{
private:bool m_inited;TT m_data[MaxLength];int m_head;int m_tail;int m_length;// 禁止拷贝构造和赋值(共享内存必须)squeue(const squeue &) = delete;squeue &operator=(const squeue &) = delete;public:squeue();void init();                // 初始化队列bool empty();               // 判断空bool full();                // 判断满int size();                 // 当前元素个数TT &front();               // 获取队头元素bool push(const TT &ee);   // 入队bool pop();                 // 出队void printqueue();          // 打印队列(调试)
};#endif

四、源文件 _public.cpp

所有成员函数实现 + 模板类显式实例化(关键)

#include "_public.h"// 构造函数
template <class TT, int MaxLength>
squeue<TT, MaxLength>::squeue()
{init();
}// 初始化队列(共享内存必须手动调用)
template <class TT, int MaxLength>
void squeue<TT, MaxLength>::init()
{if (m_inited != true){m_head = 0;m_tail = MaxLength - 1;m_length = 0;memset(m_data, 0, sizeof(m_data));m_inited = true;}
}// 判断队列是否为空
template <class TT, int MaxLength>
bool squeue<TT, MaxLength>::empty()
{return m_length == 0;
}// 判断队列是否已满
template <class TT, int MaxLength>
bool squeue<TT, MaxLength>::full()
{return m_length == MaxLength;
}// 获取元素个数
template <class TT, int MaxLength>
int squeue<TT, MaxLength>::size()
{return m_length;
}// 获取队头元素(不出队)
template <class TT, int MaxLength>
TT &squeue<TT, MaxLength>::front()
{return m_data[m_head];
}// 元素入队
template <class TT, int MaxLength>
bool squeue<TT, MaxLength>::push(const TT &ee)
{if (full()){cout << "循环队列已满,入队失败。" << endl;return false;}m_tail = (m_tail + 1) % MaxLength;m_data[m_tail] = ee;m_length++;return true;
}// 元素出队
template <class TT, int MaxLength>
bool squeue<TT, MaxLength>::pop()
{if (empty()){cout << "循环队列为空,出队失败。" << endl;return false;}m_head = (m_head + 1) % MaxLength;m_length--;return true;
}// 打印所有队列元素(调试)
template <class TT, int MaxLength>
void squeue<TT, MaxLength>::printqueue()
{for (int ii = 0; ii < size(); ii++){int idx = (m_head + ii) % MaxLength;cout << "m_data[" << idx << "], value=" << m_data[idx] << endl;}
}// 模板类显式实例化(必须,否则编译不通过)
template class squeue<int, 5>;

五、测试代码 demo1.cpp

#include "_public.h"int main()
{using ElemType = int;squeue<ElemType, 5> QQ;ElemType ee;cout << "元素(1、2、3)入队。" << endl;ee = 1; QQ.push(ee);ee = 2; QQ.push(ee);ee = 3; QQ.push(ee);cout << "队列的长度是 " << QQ.size() << endl;QQ.printqueue();ee = QQ.front(); QQ.pop();cout << "出队的元素值为 " << ee << endl;ee = QQ.front(); QQ.pop();cout << "出队的元素值为 " << ee << endl;return 0;
}

六、Makefile

必须依赖 _public.cpp,模板类不能只依赖头文件

all: demo1demo1: demo1.cpp _public.h _public.cppg++ -g -o demo1 demo1.cpp _public.cppclean:rm -f demo1

七、拓展:STL queue 原生结构

template <class T, class _Container = deque<T>>
class queue
{};

STL queue 常用接口:

  • push():元素入队

  • emplace():原地构造元素入队

  • size():获取元素个数

  • empty():判断队列是否为空

  • front():队头元素

  • back():队尾元素


八、核心知识点总结

  • 自定义循环队列无动态内存,适配共享内存

  • 使用 m_length 计数法,不牺牲存储空间

  • 共享内存中的对象不会自动初始化,必须手动调用 init()

  • 模板类必须在 cpp 文件显式实例化,否则链接失败

  • 禁止拷贝构造、赋值重载,保证共享内存安全

http://www.jsqmd.com/news/776343/

相关文章:

  • Openaibot:模块化LLM聊天机器人框架的设计、部署与优化实践
  • 国内主流吸附塔制造企业实力排行及核心能力解析 - 奔跑123
  • Saltcorn CLI工具详解:命令行操作与批量处理技巧
  • 《DNESP32P4开发指南_V1.0》第二十一章 RGBLCD实验
  • 【AISMM模型落地指南】:上市前90天合规冲刺清单与3大高频雷区避坑手册
  • 2026年清镇别墅装修与贵阳旧房翻新深度横评:从预算黑洞到透明决算的一站式整装完全指南 - 企业名录优选推荐
  • 2026年山东沥青筑路设备采购全攻略:德州霖垚与业界四大品牌深度横评 - 精选优质企业推荐官
  • 2026年郑州铝单板与氟碳铝单板市场深度横评:5大品牌选购指南与工程应用实测 - 年度推荐企业名录
  • 2026年郑州铝单板、氟碳铝单板、蜂窝铝单板全景选购指南:从幕墙到吊顶,官方联系与深度横评 - 年度推荐企业名录
  • 2026护线环批发定制:规格材质颜色灵活选,价格更便宜 - 品牌策略主理人
  • 终极解锁指南:zteOnu工具如何开启中兴光猫工厂模式与Telnet服务
  • 2026年山东沥青筑路设备全矩阵采购指南:源头厂家直达与道路养护完全方案 - 精选优质企业推荐官
  • 国内专业砖雕厂家排行 聚焦工程级供货与工艺品质 - 奔跑123
  • 行业评选2026年广州靠谱驾校 资质齐全正规推荐 - 企品推
  • 分布式爬虫平台架构设计:从权限控制到规模化数据采集实战
  • G-Helper终极指南:华硕笔记本性能优化神器,轻松降温15℃
  • 高校今年出手了!严查论文代写AI,这份期刊论文工具自救指南让你稳妥录用 - 逢君学术-AI论文写作
  • 【并购风控终极防线】:AISMM如何用动态语义映射替代传统DD问卷——来自奇点大会闭门实验的17.6倍ROI实证
  • WarcraftHelper实用指南:优化魔兽争霸3在现代系统上的游戏体验
  • Go QML高级特性:动态QML加载与运行时组件创建
  • LLMs-from-scratch-CN实战案例:构建垃圾邮件分类器与用户界面
  • 2026年乌鲁木齐断桥平开窗源头直供指南:本地工厂vs外地品牌真实对比 - 优质企业观察收录
  • 东营东城红星美凯龙欧派全屋定制:给东营人装出省心又安心的理想家 - 品牌企业推荐师(官方)
  • Element Plus项目实战:集成my-cron-vue3打造国际化定时任务管理后台
  • PyCharm里那个超大的java_error_in_pycharm.hprof文件,到底是个啥?教你一键清理释放几十G空间
  • QMCDecode:让QQ音乐加密音频在Mac上自由播放
  • openmpt是可以支持vsti插件和midi键盘的
  • 【AI面试八股文 Vol.1.4 | 专题1:Anthropic Tool Schema JSON】OpenAI / Anthropic Tool Schema JSON规范差异:逐字段拆解与面试应答
  • AI智能体规则设计:从原理到实践,构建可控高效Agent
  • 从.lib文件到实际应用:手把手教你调用STM32F4的DSP函数做FFT分析