muduo多线程异步日志学习

muduo多线程异步日志学习

以 下 为 个 人 理 解 , 可 能 存 在 错 误 之 处 。 \color{red}{以下为个人理解,可能存在错误之处。}

发送方(前端)

当新来一条日志,发送方的处理代码如下;

void AsyncLogging::append(const char* logline, int len)
{
  muduo::MutexLockGuard lock(mutex_);
  if (currentBuffer_->avail() > len){
  	// most common case: buffer is not full,copy data here
    currentBuffer_->append(logline, len);
  }else{ // buffer is full, push it, and find next spare buffer 
    buffers_.push_back(std::move(currentBuffer_));
    if (nextBuffer_){	// is there is one already,use it 
      currentBuffer_ = std::move(nextBuffer_);
    }
    else{	// allocate a new one
      currentBuffer_.reset(new Buffer); // Rarely happens
    }
    currentBuffer_->append(logline, len);
    cond_.notify();
  }
}

append()函数对应的流程图:
在这里插入图片描述
这里的几个变量:

  • currentBuffer_: 指针,指向发送方当前正在使用的缓冲区;
  • nextBuffer_:指针,指向备份缓冲区,也就是一个准备好的内存空间;
  • Buffers_:一个容器,类似于Vector,将写满了的或者不足以写当前日志的currentBuffer放进来,等待后端将Buffers_所有的元素(日志块)写入文件。

示意图:
在这里插入图片描述

发送方(后端)

void AsyncLogging::threadFunc()
{
  BufferPtr newBuffer1(new Buffer);
  BufferPtr newBuffer2(new Buffer);
  BufferVector buffersToWrite;
  while (running_)
  {
  	// swap out what need to be written, keep CS short
    {
      muduo::MutexLockGuard lock(mutex_);
      if (buffers_.empty())  // unusual usage!
      {
        cond_.waitForSeconds(flushInterval_);
      }
      buffers_.push_back(currentBuffer_.release());	// 移动,而非复制
      currentBuffer_ = boost::ptr_container::move(newBuffer1);	// 移动,而非复制
      buffersToWrite.swap(buffers_);	// 内部指针交换,而非复制
      if (!nextBuffer_)
      {
        nextBuffer_ = boost::ptr_container::move(newBuffer2);
      }
    }
    // output buffersToWrite to file
    // re-fill newBuffer1 and newBuffer2
  }
  // flush output
}

threadFunc函数流程图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值