面试二十七、异步的日志

server/2024/10/22 11:12:55/

        日志消息的写入操作在一个独立的线程中进行,而不是在调用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.ppmy.cn/server/47310.html

相关文章

MySQL 数据库实验

前言 数据库实验是抽的&#xff0c;所以仅供大家参考哦&#xff01; 查看方式 上传到云盘里面了&#xff0c;大家可以下载( •̀ ω •́ )y https://www.alipan.com/s/WE9G9bGHdnV 提取码&#xff1a;7g6c

ip反解域名-python脚本

import sys import socket from requests.packages.urllib3.contrib import pyopenssl def domain_dns(ip, port, timeout0.09): try: # 创建一个 socket sock socket.create_connection((ip, port), timeouttimeout) # 设置超时 sock.settimeout(timeout) # 加载 SSL 证书 x5…

【Uniapp微信小程序】自定义水印相机、微信小程序地点打卡相机

效果图 template 下方的image图片自行寻找替换&#xff01; <template><view><camerav-if"!tempImagePath && cameraHeight ! 0":resolution"high":frame-size"large":device-position"device":flash"f…

Flutter 中的 SliverOpacity 小部件:全面指南

Flutter 中的 SliverOpacity 小部件&#xff1a;全面指南 Flutter 是一个功能强大的 UI 框架&#xff0c;由 Google 开发&#xff0c;允许开发者使用 Dart 语言来构建高性能、美观的跨平台应用。在 Flutter 的滚动组件体系中&#xff0c;SliverOpacity 是一个用来为其子 Slive…

【ARM 嵌入式 编译系列 2.7 -- GCC 编译优化参数 -fvar-tracking-assignments 详细介绍】

文章目录 -fvar-tracking-assignments作用使用场景怎么使用注意 -fvar-tracking-assignments -fvar-tracking-assignments 是 GCC&#xff08;GNU Compiler Collection&#xff0c;GNU 编译器套件&#xff09;中的一个编译参数&#xff0c;用于优化调试体验。这个选项使得编译…

Java内存模型(JMM)

Volatile关键字 如何保证变量的可见性 在Java中&#xff0c;Volatile关键字可以保证变量的可见性&#xff0c;如果我们将变量声明为volatile&#xff0c;这就指示JVM&#xff0c;这个变量是共享且不稳定的&#xff0c;**每次使用它都到主存中进行读取&#xff08;禁止读取本地…

如何解决研发数据传输层面安全可控、可追溯的共性需求?

研发数据在企业内部跨网文件交换&#xff0c;是相对较为普遍而频繁的文件流转需求&#xff0c;基于国家法律法规要求及自身安全管理需要&#xff0c;许多企业进行内部网络隔离。不同企业隔离方案各不相同&#xff0c;比如银行内部将网络隔离为生产网、办公网、DMZ区&#xff0c…

深度学习知识与心得

目录 深度学习简介 传统机器学习 深度学习发展 感知机 前馈神经网络 前馈神经网络&#xff08;BP网络&#xff09; 深度学习框架讲解 深度学习框架 TensorFlow 一个简单的线性函数拟合过程 卷积神经网络CNN&#xff08;计算机视觉&#xff09; 自然语言处理NLP Wo…