C++实现的Buffer类

C++实现读写分离的双缓冲buffer 读写分离的双缓冲buffer有以下好处: 1. 提高了并发读写的效率:在多线程环境下,读写操作是相互竞争的,读写分离的双缓冲buffer可以有效地减少读写之间的竞争,提高并发读写的效率。 2. 减少了数据的拷贝:双缓冲buffer可以将数据从写缓冲区直接拷贝到读缓冲区,避免了中间数据拷贝的过程,提高了数据读写的效率。 3. 提高了数据的安全性:双缓冲buffer可以避免读写操作的交叉,从而保证了数据的安全性。 4. 提高了系统的稳定性:双缓冲buffer可以避免读写操作的阻塞,从而提高了系统的稳定性和可靠性 阅读详情

转自 http://blog.youkuaiyun.com/athlong0564/article/details/5942351

写C#的同志一定觉得Byte []比C++的 BYTE * 加 Length的方式好的多。一来,只需要一个对象就可以是表示一段字节流,另一方面,由于C#的特性,不需要象C++那样还要记得删除指针。由于我工作中,需要频繁地试用C#和C++,所以写了个C++的类,以便方便地管理字节流。

  很简单,先定义一个类:CMemoryBuffer。字节流内部可以用std::vector<BYTE>来保存,当然,考虑到效率,有些地方处理还是要考虑下。先把代码贴出来,然后解释为什么这么做。

  头文件:

#include <vector>
#include <queue>
#include <afxmt.h>

using namespace std;


class  CMemoryBuffer
{
public:
    CMemoryBuffer(void);
    CMemoryBuffer(const CMemoryBuffer &other);
    CMemoryBuffer(const BYTE *tpBytes ,int tiLength);
    virtual ~CMemoryBuffer(void);

    //得到内部指针——const
    const BYTE * c_Bytes() const;
    //从内部拷贝数据到数据中
    BYTE * CopyOut(int &tiLength) const;
    //确保tppBytes指向的数据足够大
    void CopyTo(const BYTE ** tppBytes, int &tiLenth) const;
    //从外部数据拷贝数据
    void CopyFrom(const BYTE * tpBytes , int tiLength);
    //从外部数据拷贝数据,添加
    void Append(const BYTE * tpBytes , int tiLength);
    void Append(const BYTE & tByte);
    //从外部数据拷贝数据,插入
    void Insert(int tiStartIndex,const BYTE * tpBytes , int tiLength);


    CMemoryBuffer & operator = (const CMemoryBuffer &other);

    CMemoryBuffer & operator += (const CMemoryBuffer &other);

    const std::vector<BYTE> &GetBuffer() const { return m_vctBuffer; }

    void Clear() ;

    int GetLength() const { return (int)m_vctBuffer.size(); }

    bool IsEmpty() const { return m_vctBuffer.size() == 0; }
    
public:
    vector<BYTE> m_vctBuffer;
};
//cpp

#include "StdAfx.h"
#include "MemoryBuffer.h"



CMemoryBuffer::CMemoryBuffer(void)
{
}

CMemoryBuffer::~CMemoryBuffer(void)
{
    this->Clear();
}

CMemoryBuffer::CMemoryBuffer(const CMemoryBuffer &other)
{
    *this = other;
}

CMemoryBuffer::CMemoryBuffer(const BYTE *tpBytes ,int tiLength)
{
    this->CopyFrom(tpBytes,tiLength);
}

void CMemoryBuffer::Clear()
{
    vector<BYTE>().swap(this->m_vctBuffer); 
}


const BYTE * CMemoryBuffer::c_Bytes() const
{
    if(this->IsEmpty()) return NULL;
    return &m_vctBuffer[0];
}

BYTE * CMemoryBuffer::CopyOut(int &tiLength) const
{
    tiLength = this->GetLength();
    if(this->IsEmpty()) return NULL;
    BYTE *pBytes = new BYTE[tiLength];
    memcpy(pBytes,&m_vctBuffer[0],tiLength);
    return pBytes;
}

void CMemoryBuffer::CopyFrom(const BYTE * tpBytes , int tiLength)
{
    this->Clear();
    if(tpBytes == NULL || tiLength == 0) return;
    m_vctBuffer.resize(tiLength,0);
    memcpy(&m_vctBuffer[0],tpBytes,tiLength);

}

void CMemoryBuffer::Append(const BYTE * tpBytes , int tiLength)
{
    if(tpBytes == NULL || tiLength == 0) return;
    m_vctBuffer.resize(this->GetLength() + tiLength,0);
    memcpy(&m_vctBuffer[0] + this->GetLength() - tiLength,tpBytes,tiLength);
}

void CMemoryBuffer::Append(const BYTE & tByte)
{
    m_vctBuffer.push_back(tByte);

}

void CMemoryBuffer::Insert(int tiStartIndex,const BYTE * tpBytes , int tiLength)
{
    if(tpBytes == NULL || tiLength == 0) return;
    int iBufferSize = this->GetLength();
    if(tiStartIndex > iBufferSize) return;
    if(tiStartIndex == iBufferSize)
    {
        this->Append(tpBytes,tiLength);
    }
    else if((tiStartIndex + tiLength) < iBufferSize)
    {
        memcpy(&m_vctBuffer[0] + tiStartIndex,tpBytes,tiLength);
    }
    else
    {
        m_vctBuffer.resize(tiStartIndex + tiLength ,0);
        memcpy(&m_vctBuffer[0] + tiStartIndex,tpBytes,tiLength);
    }

}

void CMemoryBuffer::CopyTo(const BYTE ** tppBytes, int &tiLength)const
{
    if(tppBytes == NULL || *tppBytes == NULL || this->IsEmpty()) return;
    tiLength = this->GetLength();
    memcpy(tppBytes,&m_vctBuffer[0],tiLength);

}



CMemoryBuffer & CMemoryBuffer::operator = (const CMemoryBuffer &other)
{
    this->Clear();
    if (!other.IsEmpty())
    {
        m_vctBuffer.insert(m_vctBuffer.begin(),other.GetBuffer().begin(),other.GetBuffer().end());
    }
    return *this;
}

CMemoryBuffer & CMemoryBuffer::operator += (const CMemoryBuffer &other)
{
    if (!other.IsEmpty())
    {
        m_vctBuffer.insert(m_vctBuffer.end(),other.GetBuffer().begin(),other.GetBuffer().end());
    }
    return *this;
}

解释下几点:

1、void CMemoryBuffer::Clear()
    {
     vector<BYTE>().swap(this->m_vctBuffer); 
    }

    这地方之所以要这么写,是因为vector有个毛病,clear后内存空间还不释放,需要对象释放后才释放,如果频繁操作一个大的字节流,怕影响   内存性能.

2、void CMemoryBuffer::CopyFrom(const BYTE * tpBytes , int tiLength)
{
 this->Clear();
 if(tpBytes == NULL || tiLength == 0) return;
 m_vctBuffer.resize(tiLength,0);
 memcpy(&m_vctBuffer[0],tpBytes,tiLength);

}

    很多人可能会写成一个循环语句:

    for(int i = 0; i < tiLength; i ++)

{

    m_vctBuffer.push_back(tpBytes[i]);

}

 这样写效率太低.

 




c++ 常用buffer实现 1、一个buffer缓存简单实现 #include <cstdio> #include <cstring> #include <stdlib.h> #include <malloc.h> class Buffer { public: Buffer() { m_buf = (char *)malloc(m_incr... 阅读详情

相关推荐

组件设计系列:实现一个内存工具Buffer类

在Java里面或者Netty框架里面,都有自己封装好的ByteBuffer结构,用于将应用层数据转成字节数组,最终通过网络发送出去。熟悉Java的同学可能很熟悉这些API,本文的目的是参考Netty里面的ByteBuffer封装一个类似的结构,用于C/C++项目中内存的申请及维护。 0、结构定义 对于C/C++语言来说,都是指针,因此我们需要一个结构体保存这些信息,其中total_size代表目前Buffer的容量大小。 //数据缓冲区 struct buffer { char *data;

yishuihan的博客 345

浅谈C++中的buffer

一、C++中buffer是什么?1、buffer就是缓冲区的意思。当数据从其他地方接受过来在处理前,先保存至缓冲区,然后进行发送,主要用于处理能力或效率不相同的两个设备之间进行协调。2、buffer一般用来定义数组,因为它本身的意思就是“缓冲区”,在C语言里,数组就是个缓冲区,所以用常常用它。用它没有别的意思,就是方便记,可以用shuzu mydata甚至自己名字的拼音都行,主要是用它别人也很容易...

爱学习的影峰的博客 2万+

一个c++buffer的设计和实现

基本想法: 方法1: 1、使用默认缓存5M 2、默认线程使用的内存为128K,即最多默认支持40个线程 3、初始化申请一块5M内存,然后进行分割,线程使用的定义为GROUP,没一条日志使用的为ITEM 4、运行过程中进行动态管理,内存用完后申请新的空间,一次为5M 5、线程使用完一个group后可以在使用其他的group,且不限在相同的原子buffer。 可能的问题在于,多次申请的问题,经过测试基本可以用。 方法2: 1、使用默认缓存5M 2、默认线程使用的内存为128K,即最多默认支持40个线程 3、初始化申请一块5M内存,然后进行分割,线程使用的定义为GROUP,没一条日志使用的为ITEM 4、运行过程中进行动态管理,内存用完后丢失 5、线程使用完一个group后可以在使用其他的group,且不限在相同的原子buffer。 可能的问题在于支持的线程是有上线的。 欢迎你的建议。

手把手教你实现buffer(一) —— C++中buffer的概念及需求

buffer的概念很庞大,根据不同场景,有各种各样功能的buffer,比如双缓冲buffer,jitterbuffer。这篇文章说的buffer,是指一段用于存取数据的内存空间,这是最基础的buffer。然而就是这种最基础的buffer,在C++中标准库也没有提供很通用,完善的buffer类(-_-!)。这一系列文章,将参照webrtc中的,一步步介绍如何实现这样的buffer。......

mo4776的博客 9947

C语言头文件 BUFFER

C语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件 BUFFERC语言头文件

DAZ STUDIO 快速渲染技巧

DAZ STUDIO 快速渲染技巧: 本文将向您展示几个快速渲染技巧。您将学习如何使您的Daz Iray渲染和照明在Daz工作室内更快。 当你有一个大场景,这可能需要很多小时进行渲染。 但是如果你想大幅度降低渲染时间呢?这篇文章的提示应该能让你达到这个目标。 首先,我们需要弄清楚一件事——没有“完美的环境或设置”这样的东西。是因为渲染设置是高度个性化和主观性的东西,这主要取决于场景和硬件。如果你有一个功能强大的计算机,你可以允许更多的低渲染时间,反之亦然。因此,一切都取决于您尝试渲染的对象和机器。

DAZSTUDIO的博客 9645

从零开始实现 C++ TinyWebServer 缓冲区 Buffer类详解

C++ TinyWebServer 中的缓冲区 Buffer,设计、成员变量以及核心函数的实现,代码示例。

有耐心做好简单事情,坚持写blog 1395

skywalking各项指标说明

skywalking各项指标说明

没有简介 2487

c++仿muduo库实现高并发服务器--Buffer类

减少系统调用:通过缓冲区批量读写数据(例如积累一定量数据后再send),降低read/write的调用次数。解决粘包 / 拆包:TCP 是字节流协议,Buffer通过指针管理和行读取等函数,方便解析完整的应用层协议单元(如一行数据、一个消息包)。内存高效利用:通过移动指针复用空间,减少内存分配 / 释放开销,适合高并发场景。在 muduo 等网络库中,Buffer通常与TcpConnection绑定,分别作为输入缓冲区(接收数据)和输出缓冲区(发送数据),是实现高并发的基础组件之一。

2401_89481773的博客 993

Obsidian和Typora图片路径同步终极指南:告别混乱的assets文件夹

本文详细解析了Obsidian与Typora图片路径同步的终极解决方案,通过Custom Attachment Location插件实现动态路径管理,解决了两款工具间图片兼容性问题。文章提供了从基础配置到高级应用的完整指南,帮助用户告别混乱的assets文件夹,提升工作效率。

g9h0i1的博客 821

从零到一:构建嵌入式Nginx的模块化架构与跨平台部署实战

本文详细介绍了在ARM32架构的RV1126嵌入式设备上,通过交叉编译技术构建模块化Nginx服务器的完整实战流程。涵盖环境配置、依赖库编译、Nginx核心与http_ssl_module等模块集成、性能优化及部署调试,为嵌入式开发提供高效可靠的Web服务器解决方案。

rock5的博客 202

C++ 环形Buffer 类的定义和实现

【代码】C++ 环形Buffer 类的定义和实现。

qq_57985143的博客 362

Gemini 2.5 Pro国内免魔法直连教程:5分钟搞定专业级PPT图表(附折线图/柱状图案例)

本文详细介绍了如何利用Gemini 2.5 Pro快速生成专业级PPT图表,包括折线图和柱状图等常见商业图表。通过自然语言交互和智能图表生成功能,用户可以在5分钟内完成数据可视化,大幅提升工作效率。文章还提供了实战案例和高级技巧,帮助用户轻松应对各种商业场景需求。

weixin_30733003的博客 460

C++ - 多个buffer合并成一个buffer的管理类

客户端要向服务端提交包含在多个buffer中的信息, 如果提交多个buffer(文件), 挺麻烦的.如果将这些buffer(文件), 压缩成一个文件, 处理起来也不是很方便.尝试将多个buffer封装到一个buffer中, 最终将封装好的buffer(写成文件也行)给服务端, 只需要提交一次.封装了一个管理类, 可以向管理类push多个buffer, 最后调用接口, 得到一个完整的大buffer(包含所有压入的小buffer).

博客标题不能为空 722

泛微OA与金蝶云星空审批流程对接实战:从报销单到采购合同的完整指南

本文详细介绍了泛微OA与金蝶云星空审批流程的深度集成方案,涵盖从报销单到采购合同的完整对接指南。通过API层面的无缝连接,实现流程自动化、数据同源和权限联动,显著提升企业业务效率。文章还提供了环境配置、数据映射、接口安全等实用技巧,助力企业轻松完成系统对接。

weixin_29268637的博客 245

深入URP之Shader篇1: URP Shader概述

我们知道,URP和HDRP都是基于SRP的,尽管现在可以使用Shader Graph编写Shader,但是手写Shader仍然是有一定的优势,特别是在性能方面,手写Shader可以更极致的优化,因此我们在项目中前期都是直接使用Shader Graph编写Shader,项目后期会改成手写Shader来提高性能。而在SRP中手写Shader,我们仍然使用的是Shader Lab,这个结构并没有太大的变化,但是SRP Shader中使用Shader Lab语言还是有几点不同。

聚焦游戏和图形引擎开发技术 4637

解析C++ 网络输入输出缓冲区Buffer类的设计与实现(muduo库)

网络输入输出缓冲区(Buffer)是为了优化网络通信性能而设计的。通过将数据存储在缓冲区中,可以减少对网络的频繁访问,提高数据传输效率。缓冲区还可以帮助处理数据流中的突发性和短时延,使得数据的发送和接收更加稳定和可靠。

一枚菜鸡 2073

EMD (经验模态分解) 在 C++ 中的实现指南

EMD 是由 Norden E. Huang 等人在1998年提出的一种适用于非线性和非平稳信号的分析方法。对称性:IMF 的上下包络对称。零交叉点:IMF 的零交叉点数量与极值点数量相同或相差一个。本文详细介绍了如何在C++中实现EMD,包括理论背景、算法步骤、代码实现和优化等内容。通过丰富的代码示例和详细的解释,希望能够帮助读者掌握EMD的基本原理,并能够在实际项目中灵活应用。未来,随着信号处理技术的不断发展,EMD及其变种(如EEMD、CEEMDAN等)将继续在各个领域发挥重要作用。

qq_38334677的博客 1749

从零开始编写 webserver (一) Buffer类的实现

博主是一名C++菜鸟,正在初步学习实现一个webserver的项目,希望通过编写一个自己的websever让自己对网络编程这块有更好的认识。同时也希望自己的文章在以后可以帮助到像作者一样的新人。文章可能会有一些错误,欢迎大家指正^_^

m0_74123546的博客 1317

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

从零开始实现C++ TinyWebServer(二)---- 勿在浮沙筑高台,项目地基需打稳

思来想去,不知起什么题目给这篇文章。我是准备自底向下来写这个专栏的,于是就想到了这句话(好吧其实后半句是我自己加的,不是很押韵,读着非常难受)。这句话前半句原处是出自侯捷老师的《深入浅出MFC》,引申义为做什么事都要脚踏实地,打好基础,同时做事要选择自己所擅长的和所感兴趣的方面,侯捷老师开篇第一句就告诉了我们。项目如同建筑一般,每下一层必须比上一层坚固,否则会崩塌。所以前期的选择很重要,地基很重要。

JehanRio's Private Blog 1万+

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

webserver--Buffer类实现内存缓冲区读写(全代码)

一旦数据被写入缓冲区,可以使用相应的读取方法从缓冲区中读取数据。这些方法可能包括读取指定长度的数据、读取直到特定分隔符的数据、以及将数据转换为不同的格式等。:在读写过程中可能会出现各种异常情况,例如缓冲区溢出、读取到不完整的数据等,需要相应的异常处理机制来处理这些情况,以确保系统的稳定性和可靠性。计算机本硕,人工制能研究生。:读取到数据后,可以对其进行各种处理,例如解析 HTTP 请求、执行业务逻辑、或者转发数据给其他模块。:在数据被处理完毕后,可以选择清空缓冲区,以释放内存空间,并准备接收新的数据。

dont worry about it的博客 4万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

上一篇: SOCKET 封包和拆包
下一篇: c++stack容器介绍
Syee001
博客等级 码龄14年 3粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值