c++11日志练习

/**************************************************************
技术博客 

技术交流群
群号码:324164944

欢迎c c++ windows驱动爱好者 服务器程序员沟通交流
**************************************************************/

使用c++11 写个日志类

主要练习 线程 互斥量的使用

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#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;
        }
    }
 
 
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#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

  测试代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 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;
}

  

posted on   itdef  阅读(421)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示