muduo库chat server的shared_ptr和TLS实现分析


muduo 库的 chat 最基本的是单线程模型,然后有多线程模型,但是多线程同步需要加锁,锁争用会降低服务器性能,明显的代码就是 chat server 的 onStringMessage()函数:
void onStringMessage(const TcpConnectionPtr&,
                       const string& message,
                       Timestamp)
  {
    MutexLockGuard lock(mutex_);
    for (ConnectionList::iterator it = connections_.begin();
        it != connections_.end();
        ++it)
    {
      codec_.send(get_pointer(*it), message);
    }
这个函数遍历连接列表,然后对每个连接挨个转发消息。临界区为整个函数,有相当大的优化空间。

优化方法有两种:
  • 使用 shared_ptr 做 copy-on-write
  • 使用TLS(线程局部存储)

shared_ptr 实现 copy-on-write


本文先分析如何借助 shared_ptr 实现 copy-on-write。

  • shared_ptr 是引用计数智能指针,如果当前只有一个观察者(原始创建者持有),那么引用计数为 1,可以用 shared_ptr::unique() 来判断。
  • 对于 write 端,如果发现引用计数为 1,这是可以安全地修改对象,不必担心有人在读它。
  • 对于 read 端,在读之前把引用计数加 1,读完之后减 1,这样可以保证在读的期间其引用计数大于 1,可以阻止并发写
  • 比较难的是,对于 write 端,如果发现引用计数大于 1,该如何处理? 既然更新数据,肯定要加锁,如果这时候其他线程在读,那么不能在原来的数据上修改,得创建一个副本,在副本上修改,修改完了再替换。如果没有用户在读,那么可以直接修改

使用 shared_ptr 实现 copy-on-write 的目的在于在适用于 readers-writer 场合可以降低锁竞争,提高服务器性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值