// // Created by 张衡 on 25-7-8. // #ifndef LOGGER_H #define LOGGER_H #include #include #include #include #include #include #include #include #include #include //辅助函数,多个参数转化字符串 template std::string to_string_helper(T&& arg) { std::ostringstream oss; oss << std::forward(arg); return oss.str(); } class LogQueue { public: void push(const std::string& msg) { std::lock_guard lock(mutex_); //构造好自动加锁,析构自动解锁 cond_var_.notify_one(); }; //字符串放队列中 bool pop(std::string& msg) { std::unique_lock lock(mutex_); //条件变量唤醒之后直接加锁 cond_var_.wait(lock, [this]() { return !queue_.empty() || is_shutdown_; //返回true就继续往下走 }); //消费逻辑 //队列不为空or已经关闭 if (is_shutdown_ && queue_.empty()) { return false; } msg = queue_.front(); //返回消息给msg指针 queue_.pop(); return true; }; void shutdown() { std::lock_guard lock(mutex_); is_shutdown_ = true; cond_var_.notify_all(); }; private: std::queue queue_; std::mutex mutex_; std::condition_variable cond_var_; bool is_shutdown_ = false; }; class Logger { public: Logger(const std::string& filename) : log_file_(filename, std::ios::out | std::ios::app) , exit_flag_(false) { if (!log_file_.is_open()) { throw std::runtime_error("Failed to open log file"); } worker_thread_ = std::thread([this]() { std::string msg; while (log_queue_.pop(msg)) { log_file_ << msg << std::endl; } }); }; ~Logger(); template void log(const std::string& format, Args&& ...args); private: LogQueue log_queue_; std::thread worker_thread_; std::ofstream log_file_; std::atomic exit_flag_; }; #endif //LOGGER_H