/**************************************************************
技术博客 
技术交流群
群号码: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;
}

  

最新文章

  1. jenkins入门
  2. hibernate和mybatis的区别
  3. BZOJ4519: [Cqoi2016]不同的最小割
  4. labview 中activex的初步使用方法
  5. ios 获取字符串所需要占用的label的高度
  6. db2 alter table 语法
  7. C#中启动外部应用程序
  8. CCI_chapter 16 Low level
  9. 在IE6/7下表格td标签没有内容时不显示边框?
  10. 取代奶瓶Minidwep-gtk 破 WPA 全攻略
  11. 前端开发必备之MDN文档
  12. [HNOI2011]XOR和路径 &amp;&amp; [HNOI2013]游走
  13. MongoDB存储引擎(下)——In-Memory
  14. 文件上传的一个坑 Apache上传组件和SpringMVC自带上传冲突
  15. Java学习笔记(二十四):单例设计模式singleton
  16. python中迭代器和生成器的区别
  17. Spring Boot 2.0 入门指南
  18. 【转】vue中动态设置meta标签和title标签
  19. 牛掰本机限速软件appband
  20. boost::asio::deadline_timer(理解)

热门文章

  1. Apache Maven 入门篇
  2. quartz 的简单使用
  3. bootstrap做的导航
  4. bootstrap左侧边栏
  5. mysql大表优化
  6. Delphi WebBrowser 无法调用当前浏览器的版本 --转
  7. 如何选择 SQL Server 数据库跟操作系统版本
  8. Linux多网卡负载均衡 : bond
  9. while and for 2
  10. 与servlet相关的接口