/**************************************************************
技术博客
技术交流群
群号码:324164944
欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
**************************************************************/
使用c++11 写个日志类
主要练习 线程 互斥量的使用
代码如下:
#include "stdafx.h"
#include "Logger.h"
#include <fstream>
#include <iostream>
Logger::Logger(const string& filepath):
filePath_(filepath)
{
}
Logger::~Logger()
{
thread_.join();
}
bool Logger::init()
{
bool bRet = false;
thread_ = thread{ &Logger::LogThreadFunc, this };
unique_lock<mutex> lock(mutexStarted_);
condVarStarted_.wait(lock);
bRet = true;
return bRet;
}
void Logger::Log(const std::string& content)
{
unique_lock<mutex> lock(mutex_);
queue_.push(content);
}
void Logger::LogThreadFunc()
{
ofstream ofs(filePath_);
if (ofs.fail()) {
cerr << "Failed to open logfile." << endl;
return;
}
cout << "enter thread" << endl;
unique_lock<mutex> lock(mutex_,std::defer_lock);
condVarStarted_.notify_all();
while (true){
lock.lock();
condVar_.wait(lock);
lock.unlock();
while (true){
lock.lock();
if (queue_.empty()) {
lock.unlock();
break;
}
else {
ofs << queue_.front() << endl;
queue_.pop();
}
lock.unlock();
}
if (bExit_){
break;
}
}
}
#ifndef LOGGER_H__
#define LOGGER_H__
#include <queue>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#define DEFAULT_FILE_NAME "test.dat"
using namespace std;
class Logger{
public:
Logger(const string& filepath = DEFAULT_FILE_NAME);
virtual ~Logger();
bool init();
void Log(const std::string& content);
void LogThreadFunc();
void SetExitFlag(){
bExit_ = true;
condVar_.notify_all();
};
private:
string filePath_;
bool bExit_;
std::condition_variable condVar_;
std::condition_variable condVarStarted_;
std::thread thread_;
std::mutex mutex_;
std::mutex mutexStarted_;
std::queue<std::string> queue_;
Logger& operator=(const Logger& rhs);
};
#endif
测试代码如下:
// 1111.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Logger.h"
#include <iostream>
#include <sstream>
#include <thread>
#include <vector>
void logSomeMessages(int id, Logger& logger)
{
for (int i = 0; i < 100; ++i) {
stringstream ss;
ss << "Log test " << i << " from thread " << id;
logger.Log(ss.str());
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Logger log;
log.init();
vector<thread> threads;
// Create a few threads all working with the same Logger instance.
for (int i = 0; i < 100; ++i) {
threads.push_back(thread{ logSomeMessages, i, ref(log) });
}
for (auto& t : threads) {
t.join();
}
log.SetExitFlag();
return 0;
}