面试二十七、异步的日志

        日志消息的写入操作在一个独立的线程中进行,而不是在调用log函数的主线程中进行。这意味着主线程可以继续执行其他任务,而不需要等待日志消息写入完成。这提高了程序的性能和响应速度,特别是在日志写入操作耗时较长的情况下。

#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <atomic>class AsyncLogger {
public:AsyncLogger(const std::string& filename) : logFile(filename, std::ios::out | std::ios::app), isRunning(true), logThread(&AsyncLogger::processLogs, this) {if (!logFile.is_open()) {throw std::runtime_error("Failed to open log file.");}}~AsyncLogger() {{std::unique_lock<std::mutex> lock(mutex);isRunning = false;condVar.notify_all();}logThread.join();}void log(const std::string& message) {std::unique_lock<std::mutex> lock(mutex);logQueue.push(message);condVar.notify_all();}private:void processLogs() {while (isRunning || !logQueue.empty()) {std::unique_lock<std::mutex> lock(mutex);condVar.wait(lock, [this]() { return !logQueue.empty() || !isRunning; });while (!logQueue.empty()) {logFile << logQueue.front() << std::endl;logQueue.pop();}}}std::ofstream logFile;std::atomic<bool> isRunning;std::thread logThread;std::queue<std::string> logQueue;std::mutex mutex;std::condition_variable condVar;
};int main() {try {AsyncLogger logger("async_log.txt");logger.log("Log message 1");logger.log("Log message 2");logger.log("Log message 3");std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟其他工作logger.log("Log message 4");// 等待一段时间以确保所有日志都被处理std::this_thread::sleep_for(std::chrono::seconds(2));} catch (const std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}return 0;
}

代码解释

  1. AsyncLogger类:管理异步日志记录功能。

    • logFile:日志文件流,用于写入日志消息。
    • isRunning:标志异步日志线程是否运行。
    • logThread:处理日志消息的线程。
    • logQueue:存储待写入的日志消息。
    • mutex:保护共享数据的互斥量。
    • condVar:条件变量,用于线程间通信。
  2. 构造函数和析构函数

    • 构造函数打开日志文件并启动日志线程。
    • 析构函数关闭日志线程并确保所有日志消息都被处理。
  3. log函数:将日志消息添加到队列中,并通知日志线程有新消息需要处理。

  4. processLogs函数:日志线程运行的函数,不断从队列中取出日志消息并写入日志文件。

进一步改进

  1. 添加日志级别(例如INFO, WARN, ERROR)。
  2. 处理日志写入失败的情况。
  3. 实现一个线程安全的队列来提高代码的健壮性。

a. 添加日志级别支持,例如INFO、WARN、ERROR。
b. 改进日志系统以处理日志文件写入失败的情况

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/845027.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文总结:Grasp-Anything: Large-scale Grasp Dataset from Foundation Models

目录 一、论文摘要 二、Grasp-Anything数据集 A. 场景生成 B. 抓取姿势标注 ​编辑 C. Grasp-Anything统计 D. Grasp-Anything对社区的帮助 三、实验 A. 零样本抓取检测 B. 机器人评估 C. 野外抓取检测 D. 讨论 四、总结 论文&#xff1a;https://arxiv.org/pdf/2…

Kafka系列之高频面试题

基础 简介 特点&#xff1a; 高吞吐、低延迟&#xff1a;kafka每秒可以处理几十万条消息&#xff0c;延迟最低只有几毫秒&#xff0c;每个Topic可以分多个Partition&#xff0c;Consumer Group对Partition进行Consumer操作可扩展性&#xff1a;Kafka集群支持热扩展持久性、可…

AVFrame相关接口(函数)

分配和释放 分配 AVFrame AVFrame *av_frame_alloc(void); 分配一个新的 AVFrame 并返回一个指向它的指针。返回的 AVFrame 需要手动释放。 释放 AVFrame void av_frame_free(AVFrame **frame); 释放由 av_frame_alloc 分配的 AVFrame。这个函数会释放帧的数据并将指针设为 …

STM32启动过程分析

Keil堆栈设置注意事项 一、启动模式 复位方式&#xff1a;上电复位、硬件复位、软件复位 从地址0x0000 0000处取出堆栈指针MSP的初始值&#xff0c;该值就是栈顶地址。从地址0x0000 0004处取出程序计数器指针PC的初始值&#xff0c;该值指向复位后执行的第一条指令。 说白了就…

基于模板匹配的信用卡数字识别

文章目录 一、项目介绍二、模板匹配的原理三、模板匹配的步骤模板图片处理信用卡图片处理进行模板匹配 一、项目介绍 模板识别&#xff08;Template Matching&#xff09;是一种基于图像匹配的技术&#xff0c;用于在较大图像中识别和定位小图像&#xff08;模板&#xff09;。…

YOLO目标检测:框架技术原理和代码实现

Dream推荐 适读人群 &#xff1a;本书适合对YOLO目标检测感兴趣、了解深度学习相关概念的算法工程师、软件工程师等人员阅读。 全面&#xff1a;涵盖6个常用目标检测框架&#xff08;YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOX、YOLOv7&#xff09;的发展状况、技术原理和代码实…

等保系列之——网络安全等级保护测评工作流程及工作内容

#等保测评##网络安全# 一、网络安全等级保护测评过程概述 网络安全等级保护测评工作过程包括四个基本测评活动&#xff1a;测评准备活动、方案编制活动、现场测评活动、报告编制活动。而测评相关方之间的沟通与洽谈应贯穿整个测评过程。每一项活动有一定的工作任务。如下表。…

go语言初学03 连接mysql

使用 Go 语言连接 MySQL 数据库通常涉及几步简单的配置和编程。以下是详细的步骤&#xff0c;帮助你从安装依赖到进行基本的数据库操作。 1. 安装 MySQL 数据库驱动 首先&#xff0c;你需要安装 MySQL 数据库驱动。推荐使用 go-sql-driver/mysql&#xff0c;这是一个流行且被…

java.lang.IllegalArgumentException: invalid pointerIndex -1 for MotionEvent

问题描述 错误 AndroidRuntime: java.lang.IllegalArgumentException: invalid pointerIndex -1 for MotionEvent 表示由于无效的指针索引导致 Android 应用程序崩溃MotionEvent目的。此错误通常发生在应用处理触摸事件时&#xff0c;尤其是使用ViewPager在不同的视图或页面之…

【Spring EL<一>✈️ 】SL 表达式的应用

目录 &#x1f378;前言 &#x1f37b;一、Spring EL 1.1 定义 1.2 常见使用方式 &#x1f37a;二、项目案例 2.1 实现一个简单的案例 2.2 创建注解 2.3 切面类实现 2.4 创建测试接口 2.5 测试 &#x1f379;三、章末 &#x1f378;前言 小伙伴们大家好&#xff0c;前段时间…

32. 【Java教程】集合

在前面的小节中&#xff0c;我们学习了数组&#xff0c;本小节学习的集合同样用于存放一组数据&#xff0c;我们将学习什么是集合、集合的应用场景 &#xff0c;在应用场景部分我们将对比 Java 数组与集合的区别&#xff0c;还将系统介绍 Java 集合的架构&#xff0c;也将结合实…

【观察】数字化生存时代已来临,能源转型如何实现“再升级”?

20多年前&#xff0c;尼古拉斯尼葛洛庞帝在《数字化生存》一书中预言&#xff1a;“数字化生存是现代社会中以新技术为基础的新的生存方式。” 随着数字经济的蓬勃发展&#xff0c;尼葛洛庞帝的预言逐渐被验证。今天&#xff0c;新技术带来的数字化和智能化正全方位影响着经济…

【赠书第27期】向AI提问的艺术:提示工程入门与应用

文章目录 前言 1 问题的构建 1.1 明确性与具体性 1.2 结构化与层次性 1.3 相关性与针对性 2 提问的技巧 2.1 简洁明了 2.2 避免歧义 2.3 使用自然语言 3 与AI的互动策略 3.1 耐心与理解 3.2 逐步引导 3.3 反馈与调整 4 总结与展望 5 推荐图书 6 粉丝福利 前言 …

定时器与PWM的LED控制

目录 一、基础概念定时器定时器类型定时器特性 PWM定义占空比原理 二、实验1.LED周期性亮灭定时器TIM2配置GPIO引脚设置工程相关参数配置Keil编写程序 2.LED呼吸灯(PWM)呼吸灯原理Keil编写程序Keil虚拟示波器&#xff0c;观察 PWM输出波形设置点击setup&#xff0c;并设置观察引…

Sapphire开发日志(三)

任务描述 本周实现并封装了模型的运行&#xff0c;需要在前端安装依赖的库&#xff0c;编写对应的处理函数。同时需要能够展示出抠图效果。 依赖与环境配置 尝试在前端接入并运行onnx。 在前端运行onnx依赖于onnxruntime-web这个包&#xff0c;这个包可以在浏览器进行模型推…

antV+vue3 单选框选中加入逻辑运算,再次点击取消选中,不计入逻辑运算

文章目录 antVvue3 单选框选中加入逻辑运算&#xff0c;再次点击取消选中&#xff0c;不计入逻辑运算需求增加点击事件逻辑处理效果 antVvue3 单选框选中加入逻辑运算&#xff0c;再次点击取消选中&#xff0c;不计入逻辑运算 需求 在做项目时&#xff0c;多次遇到单选框需要再…

【2024新版】银系统源码/超市收银系统/智慧新零售/ERP进销存管理/线上商城/商户助手

>>>系统简述&#xff1a;本系统适用于超吃便利店&#xff0c;美妆母婴行业&#xff0c;服装鞋帽行业&#xff0c;食品零售行业&#xff0c;3C数码电子行业&#xff0c;食品生鲜等一切零售行业&#xff0c;产品功能角色介绍如下 合伙人&#xff1a;无限发展代理商和商…

Pod 控制器

前言 Pod 是 Kubernetes 集群中能够被创建和管理的最小部署单元。所以需要有工具去操作和管理它们的生命周期,这里就需要用到控制器了。 Pod 控制器由 master 的 kube-controller-manager 组件提供&#xff0c;常见的此类控制器有 Replication Controller、ReplicaSet、Deploym…

React-生成随机数和日期格式化

生成随机数 uuid文档&#xff1a;https://github.com/uuidjs/uuid npm install uuid import {v4 as uuidV4} from uuid 使用&#xff1a; uuidV4() 日期格式化 dayjs文档&#xff1a;安装 | Day.js中文网 npm install dayjs import dayjs from dayjs

算法-扫描线

目录 什么是扫描线算法&#xff1f; 扫描线简单应用 更多的扫描线 什么是扫描线算法&#xff1f; 在计算几何中&#xff0c;扫描线算法&#xff08;scan line algorithm&#xff09;一般用来解决几何图形的面积交并&#xff0c;周长交并问题&#xff0c;扫描线算法的核心思想…