您当前的位置: 首页 >  c++

qianbo_insist

暂无认证

  • 0浏览

    0关注

    399博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

c++千万数据级别正确使用无锁队列,避免内存撕碎(二)

qianbo_insist 发布时间:2022-08-25 22:04:23 ,浏览量:0

第一篇文章 这里逐渐深入,先讲一下协议,很多概念必须讲清楚

七层协议

我们使用的是网络传输,千万级别的数据实际上并不多,对于队列来说,每个队列的数据块大小定义为MTU大小,如1400字节,实际上传输层定义在操作系统里面,我们无法更改,无论是linux还是windows,都需要经过内核态和用户态,假定我们有100路视频, 每路视频为2M 码流, 一分钟有多少数据呢, 2 * 1024*1024 / 8 * 60 * 100 = 1572864000 bytes = 1500 G 对于MTU 包个数来说, 是 1500G / 1400 = 1G 个队列包, 那每秒钟就是 1024 * 1024 / 60 = 17476 个队列包, 每路有 17476 / 100 = 175 个 MTU包,对于带宽来说,上传就需要200Mbit的带宽,所以这里千万数据级别,说的就是1分钟MTU的包个数。

会话层来说,如果传输层协议使用tcp, 100个上传就需要100个会话,到应用层的时候需要发送的RTP协议实际上每个包都会加上至少12个字节的包头。这些都是开销,选择RTMP协议和RTSP,SIP等等,各自都有开销,但是RTSP和SIP 传输层都可以是 RTP协议 ,也都可以选择UDP和TCP,选择UDP意味着更低的开销,TCP 意味着丢包会少。 在这里插入图片描述

应用方

主要应用在视频传输方面,下面画出主要的视频传输,无论使用什么协议,我们先关注在RTP协议上面,RTP协议首先为UDP,RTP over UDP协议我们主要关注在他的包数量和缓冲的内存数量上,我们这样来计算,对于2Mbit 的视频传输来说, 我们有如下算法 MTU = 1400 2M 约为 210241024 /8 /1400 = 187

也就是如果需要缓存1秒数据,至少需要187 个缓存单元,有了如上计算,我们就可以假定一个视频为2M的单元来说,我们缓存200 个单元,每个单元大小为1400字节。 在这里插入图片描述

数据量极大

大数据量莫过于视频,尤其是RTP协议中的包,1是多,每个RTP协议包数据量不会超过MTU,最大传输单元,

#include 
#include 
#include 
enum
{
    en_emptying = 0,
    en_writing,
    en_canreadings
};
struct smem
{
    char v_status;
    char v_i_flag;
    char r1;
    char r2;
    int v_len = 0;
    uint32_t v_pts = 0;
    uint8_t* v_data = NULL;
};

typedef std::shared_ptr ptr_smem;

struct s_mem_pool
{
    //qianbo :just one thread read,one thread write ,otherwise error occur
    uint8_t* v_data = NULL;
    uint8_t* v_end = NULL;
    int v_len = 0;;
    uint8_t* v_write = NULL;
    uint8_t* v_read = NULL;

    std::mutex v_mux;
    std::atomic_int v_framenum;
    std::queuev_i;
    void init_mem(int memlen)
    {
        if (v_data != NULL)
        {
            if (v_len v_data = v_write;\
        mem->v_len = len;\
        mem->v_pts = pts;\
        mem->v_i_flag = i_flag; \
        mem->v_status = en_writing;\
        v_mux.lock();\
        v_i.emplace(mem);\
        v_mux.unlock();

#define WRITE_INFO2 \
    uint8_t *m = v_write; \
    *(char*)(m) = (char)en_writing; \
    m +=1; \
    *(char*)(m) = (char)i_flag;\
    m +=3; \
    *(int*)m = len; \
    m +=4; \
    *(uint32_t*)m = pts; \
    m+= 4;\
    v_write = m;


        if (v_write >= v_read)
        {
            if ((v_end - v_write) > (long)(NEEDLEN))
            {

                memcpy(v_write, data, len);
                WRITE_INFO
                    v_write += (NEEDLEN);
                v_framenum++;
                return true;
            }
            else // the left mem is not enough
            {
                //qInfo()            
关注
打赏
1663161521
查看更多评论
0.0398s