前言
日志系统的作用在于能够在整个项目期间帮助调试,定位错误,测试验证等。日志系统能够写日志但不能占用主线程时间去写,因此要设计一个异步日志系统。
1. 预备知识
1.1 单例模式
保证一个类仅有一个实例被构造,并提供一个访问它的全局访问接口,该实例被程序的所有模块共享,因此可以节省系统资源。
<aside>
💡 单例模式的关键特点
</aside>
- 全局单一实例。
- 全局的访问点,其他对象可以通过该访问点获取单例实例。
- 延迟加载(可选):在需要时才进行单例对象的创建,可以减少应用程序启动时的资源占用。
- 线程安全性(可选):在多线程环境下,单例模式需要考虑线程安全性,以确保只有一个实例被创建。
<aside>
💡 大致的实现方法
</aside>
- 定义一个单例类;
- 私有化构造函数,防止外界直接创建单例类的对象;
- 禁用拷贝构造,移动赋值等函数,可以私有化,也可以直接使用
=delete
;
- 使用一个公有的静态方法获取该实例;
- 确保在第一次调用之前该实例被构造。
<aside>
💡 两种实现方式
</aside>
- 懒汉模式:懒汉模式是延迟加载的,也就是说,单例对象在首次访问时才进行初始化。在多线程环境中,可能会出现竞态条件,需要额外的线程安全措施来确保只创建一个实例。但是,其中在C++11后,不需要加锁,直接使用函数内局部静态对象即可。C++保证静态变量的构造是线程安全的,从C++11开始,保证局部静态变量的构造也是线程安全的,这些是编译器自动完成的,我们不需要考虑。
- 饿汉模式:应用程序启动时就进行单例对象的初始化,无论是否会被使用。因此,单例对象在应用程序生命周期内都存在。
- 如何选择:如果应用程序对资源要求敏感,希望尽量减少启动时的内存占用,或者需要支持延迟加载,可以选择懒汉模式。如果应用程序对性能要求高,可以接受在应用程序启动时进行初始化,并且不希望处理多线程环境下的线程安全问题,可以选择饿汉模式。