博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(P48)muduo库使用例子(七):高效率多线程异步日志
阅读量:4299 次
发布时间:2019-05-27

本文共 1511 字,大约阅读时间需要 5 分钟。

文章目录

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);

在这里插入图片描述

在这里插入图片描述

1:13:41

转载地址:http://fqiws.baihongyu.com/

你可能感兴趣的文章
eclipse安装插件的两种方式在线和离线
查看>>
linux下源的相关笔记(suse)
查看>>
linux系统分区文件系统划分札记
查看>>
Linux(SUSE 12)安装Tomcat
查看>>
Linux(SUSE 12)安装jboss4并实现远程访问
查看>>
Neutron在给虚拟机分配网络时,底层是如何实现的?
查看>>
netfilter/iptables全攻略
查看>>
Overlay之VXLAN架构
查看>>
Eclipse : An error occurred while filtering resources(Maven错误提示)
查看>>
在eclipse上用tomcat部署项目404解决方案
查看>>
web.xml 配置中classpath: 与classpath*:的区别
查看>>
suse如何修改ssh端口为2222?
查看>>
详细理解“>/dev/null 2>&1”
查看>>
suse如何创建定时任务?
查看>>
suse搭建ftp服务器方法
查看>>
centos虚拟机设置共享文件夹并通过我的电脑访问[增加smbd端口修改]
查看>>
文件拷贝(IFileOperation::CopyItem)
查看>>
springboot(三) 用druid连接mybatis
查看>>
springboot(四) 用mybatis-generator自动生成bean和dao
查看>>
springboot(五)读写分离,多个读库,Druid监控
查看>>