池化技术
池化技术可以减少很多的底层重复工作,例如创建进程、线程、申请内存空间时的系统调用和初始化工作。例如线程池,先预先创建好一些线程,当任务到来时直接将预先创建好的线程唤醒去处理任务,效率会远远高于任务到来时临时创建线程。例如内存池,但我们要用 1mb 空间时内存池会一次性申请 20mb 空间,效率会远远高于用多少空间申请多少空间(申请空间会调用系统调用)。 线程池是执行流级别的池化技术,STL 中的空间配置器和内存池是内存块管理级别的池化技术。
线程池的日志模块
下面开始,我们结合之前所做的所有封装,进行一个线程池的设计。在写之前,我们要做如下准备。
- 准备线程的封装
- 准备锁和条件变量的封装
- 引入日志,对线程进行封装
日志与策略模式
什么是设计模式 IT 行业这么火,涌入的人很多。俗话说林子大了啥鸟都有。大佬和菜鸡们两极分化的越来越严重。为了让菜鸡们不太拖大佬的后腿,于是大佬们针对一些经典的常见的场景,给定了些对应的解决方案,这个就是设计模式。
什么是日志 计算机中的日志是记录系统和软件运行中发生事件的文件,主要作用是监控运行状态、记录异常信息,帮助快速定位问题并支持程序员进行问题修复。它是系统维护、故障排查和安全管理的重要工具。 日志格式以下几个指标是必须得有的 时间戳 日志等级(严重程度) 日志内容 以下儿个指标是可选的 文件名行号 进程,线程相关 id 信息等
日志有现成的解决方案,如:spdlog、glog、Boost.Log、Log4cxx 等等,我们依旧采用自定义日志的方式。 这里我们采用设计模式中的策略模式来进行日志的设计,具体策略模式介绍,详情看下文。 我们想要的日志格式如下:
日志模块
两个核心问题
- 日志内容的刷新策略,刷新到显示器或文件或网络。
- 构建一条完整的日志。
设计文件等级
我们知道枚举类型中的枚举值(编译期常量)的底层存储是整数,所以我们需要把它们转换成字符串输出。(补充:枚举值的类型就是枚举类本身)
// Logger.hpp
// C++11 支持的强枚举,访问成员需指定作用域,不易出现命名冲突
enum class LogLevel {
DEBUG,
INFO, // 正常消息
WARNING, // 出现错误,但不影响程序运行
ERROR, // 导致程序退出的错误
FATAL // 重大错误
};
std::string Level_to_string(LogLevel level) {
switch (level) {
case LogLevel::DEBUG: return "DEBUG";
case LogLevel::INFO: return "INFO";
case LogLevel::WARNING: ;
LogLevel::ERROR: ;
LogLevel::FATAL: ;
: ;
}
}






