C++ 双缓存机制

前来填坑。

背景:

先说一下双缓存的应用场景。消息中心不断的派发数据下来,一个线程接收派发下来的数据(成为接收线程),另一个线程对数据进行处理(成为工作线程)。很显然,我们期望接收数据的线程能够尽快把数据接收进来,同时工作线程也尽可能减少对接收线程的影响。举一个实际场景,用户连接管理,一方面要处理用户的连接请求,连接上的用户入队,另一方面不断的检测用户的心跳包,释放超时用户。

1.简单实现

   一种比较容易想到的实现是用一个列表来缓存数据,有新用户连进来时加锁,入队,另一个线程里定时检测列表,超时的用户进行释放。代码如下

class Buffer
{
public:
    void AddUser(int n)
    {
        // 有新用户时入队
        std::lock_guard<std::mutex> lock(m_lock);
        m_listUser.push_back(n);
    }

    void OnTimer()
    {
        std::lock_guard<std::mutex> lock(m_lock);
        for (auto iter = m_listUser.begin(); iter != m_listUser.end();)
        {
            // 定时遍历所有用户,超时的释放掉
            if (IsTimeout(*iter))
            {
                iter = m_listUser.erase(iter);
                
            }
            else
            {
                ++iter;
            }
        }
    }

    bool IsTimeout(int n)
    {
        return false;
    }
private:
    std::mutex m_lock;
    std::list<int> m_listUser;
};

这种方式简单,但是问题也很明显。检测时将列表锁住了 ,这时候新用户无法建立连接,如果用户数量很多,就造成了连接阻塞。

2.双缓存实现

将用户分为连接中用户和已连接用户。

class Buffer
{
public:
    void AddUser(int n)
    {
        // 有新用户时加入到连接用户的队列
        std::lock_guard<std::mutex> lock(m_lock);
        m_listConnectingUser.push_back(n);
    }

    void OnTimer()
    {
        std::list<int> listTmp;
        {
            // 只对连接中的用户加锁,同时加锁操作只有一个swap,锁的竞争很小
            std::lock_guard<std::mutex> lock(m_lock);
            listTmp.swap(m_listConnectingUser);
        }

        for (auto iter = m_listConnectedUser.begin(); iter != m_listConnectedUser.end();)
        {
            // 只遍历已连接的用户
            if (IsTimeout(*iter))
            {
                iter = m_listConnectedUser.erase(iter);
                
            }
            else
            {
                ++iter;
            }
        }

        // 连接中的用户专为已连接的用户
        for (int tmp : listTmp)
        {
            m_listConnectedUser.push_back(tmp);
        }
    }

    bool IsTimeout(int n)
    {
        return false;
    }
private:
    std::mutex m_lock;
    std::list<int> m_listConnectingUser;
    std::list<int> m_listConnectedUser;
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值