面试二十七、异步的日志

        日志消息的写入操作在一个独立的线程中进行,而不是在调用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. 改进日志系统以处理日志文件写入失败的情况

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值