(P48)muduo库使用例子(七):高效率多线程异步日志

1.多线程程序日志库要求

  • 线程安全,即多个线程可以并发写日志,两个线程的日志消息不会出现交织。
    (1)用一个全局的mutex保护IO
    (2)每个线程单独写一个日志文件

  • 前者造成全部线程抢占一个锁,会造成写日志变成了串行

  • 后者有可能让业务线程阻塞在写磁盘操作上,影响业务线程的并发能力

  • 解决办法:用一个背景线程(日志线程,后端线程)负责收集日志消息,并写入日志文件,其他业务线程(前端线程)只管往这个“日志线程”发送日志消息(不是实时的),这称为“异步日志”(用非阻塞日志描述更加准确,前端业务线程将日志写到缓冲区中,不涉及到日志文件的写操作,所以可以称之为日志文件的非阻塞操作),并不影响业务线程并发写日志,前端的业务线程不会阻塞的,因为是写到缓冲区中的。
    (1)生产者与消费者
    前端(业务线程)生产者,多个
    后端(日志线程)消费者,1个
    缺点:写文件操作比较频繁,效率比较低

生产者
p(semfull)
	p(mutex)
	往队列中添加一条日志消息
	v(mutex)
v(semempty)

消费者
p(semempty)
	p(mutex)
	从队列中取出所有的日志消息,写入到文件中
	v(mutex)
v(semfull)
  • muduo采用多缓冲机制,multiple buffering
    前端(业务线程)生产者,多个
    后端(日志线程)消费者,1个
    优点:使得前端的业务线程与后端的日志线程能够并发,且写日志不太频繁,提高了效率。
    (1)前端业务线程将日志写到currentBuffer_,nextBuffer_是后备的一块缓冲区,buffers_是要写入到日志文件的缓冲区列表;
    (2)currentBuffer_写满后,添加到buffers_,会通知后端的日志线程写日志文件,currentBuffer_不写满,后端线程是不会将数据写入到日志文件中的,但是此时其他业务线程往nextBuffer_又写入一部分数据了,没写满,此时currentBuffer_需要指向nextBuffer_所指向的缓冲区;
    (3)后端日志线程得到通知后,此时前端的currentBuffer_没有满,也会将其添加到buffers_中,前端从buffers_中取出数据;将buwBuffer1_缓冲区给currentBuffer_,将newBuffer2_缓冲区给nextBuffer_,保证前端的业务线程还能写日志消息到缓冲区中。
    (4)当buffer_缓冲区的数据写完之后,还需要预留2块缓冲区给newBuffer1_和newBuffer2_
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    (5)若写日志并不是很频繁,没有办法将一块缓冲区填满的话,经过3s后,也会把没有填满的缓冲区写入到日志文件,即:写入到日志文件不一定是实时的,只要写入到日志文件就行

  • eg:48\jmuduo\muduo\base\AsyncLogging.h
    48\jmuduo\muduo\base\AsyncLogging.cc

  • eg测试:48\jmuduo\muduo\base\tests\AsyncLogging_test.cc
    48\jmuduo\muduo\base\tests\CMakeLists.txt
    48\jmuduo\muduo\base\CMakeLists.txt

  • 测试:下面的每行是每次写入1000条消息的时间
    在这里插入图片描述
    生成的日志文件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

注释掉下面的代码,产生消息堆积,回丢失一部分消息,日志也没那么大了
    struct timespec ts = { 0, 500*1000*1000 };//睡眠0.5秒
    nanosleep(&ts, NULL);

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢打篮球的普通人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值