c++ 日志输出库 spdlog 简介(4)- 多线程txt输出日志
在上一节的代码中加入了向文本文件中写入日志的代码:
UINT CMFCApplication1Dlg::Thread1(LPVOID pParam)
{
try{
size_t q_size = ; //queue size must be power of 2
spdlog::set_async_mode(q_size, spdlog::async_overflow_policy::block_retry);
auto console = spd::stdout_color_st("console1");
for (int i = ; i < ; i++){
Sleep();
console->info("Thread 1,Count {}",i);
Sleep();
auto daily = spd::basic_logger_mt("basic1", "logs/basic-log.txt");
daily->info("Thread 1,Count {}", i);
spdlog::drop("basic1"); }
}
catch (const spd::spdlog_ex& ex)
{
std::cout << "Thread 1 Logger failed: " << ex.what() << std::endl;
}
spdlog::drop("console1");
return ;
}
UINT CMFCApplication1Dlg::Thread2(LPVOID pParam)
{
try{
size_t q_size = ; //queue size must be power of 2
spdlog::set_async_mode(q_size, spdlog::async_overflow_policy::block_retry);
auto console = spd::stdout_color_st("console2");
//auto daily2 = spd::basic_logger_mt("basic2", "logs/basic-log.txt");
for (int i = ; i < ; i++){
Sleep();
console->info("Thread 2,Count {}", i);
auto daily = spd::basic_logger_mt("basic2", "logs/basic-log.txt");
daily->info("Thread 2,Count {}", i);
spdlog::drop("basic2");
}
}
catch (const spd::spdlog_ex& ex)
{
std::cout << "Thread 2 Logger failed: " << ex.what() << std::endl;
}
spdlog::drop("console2");
return ;
}
实验表明,两个线程同时运行,由于写入一个的是同一个txt文件basic-log.txt,运行时会发生异常,如下图第二行的 Permission denied。

由于线程1打开了basic-log.txt文件,在其关闭文件也就是drop之前如果线程2也去打开这个文件,就会发生冲突。
如何解决呢?
(1)ex.what()返回const char * 类型,也就是字符串指针,可以在catch中判断异常类型,如果是Permission denied这种类型的异常,可以重新申请输出日志。
(2)或者用一个线程锁,防止两个线程同时访问一个文件。
首先定义两个全局变量:
HANDLE hEvent1 = NULL;
HANDLE hEvent2 = NULL;
然后在按钮函数中初始化两个Event:
void CMFCApplication1Dlg::OnBnClickedButton1()
{
hEvent1 = CreateEvent(NULL, TRUE, FALSE, NULL);//手动复位,初始为无信号
hEvent2 = CreateEvent(NULL, TRUE, TRUE, NULL);//手动复位,初始为有信号
AfxBeginThread(Thread1, this);
AfxBeginThread(Thread2, this);
}
在线程函数中设定互锁机制:
UINT CMFCApplication1Dlg::Thread1(LPVOID pParam)
{
try{
//size_t q_size = 4096; //queue size must be power of 2
//spdlog::set_async_mode(q_size, spdlog::async_overflow_policy::block_retry);
auto console = spd::stdout_color_st("console1");
for (int i = ; i < ; i++){
Sleep();
DWORD dReturn = WaitForSingleObject(hEvent2, INFINITE);
if (WAIT_OBJECT_0 == dReturn)
{
console->info(" Event2 signaled ! ");
ResetEvent(hEvent2);
Sleep();
}
console->info("Thread 1,Count {}",i);
auto daily = spd::basic_logger_mt("basic1", "logs/basic-log.txt");
daily->info("Thread 1,Count {}", i);
spdlog::drop("basic1");
SetEvent(hEvent1);
Sleep();
}
}
catch (const spd::spdlog_ex& ex)
{
std::cout << "Thread 1 Logger failed: " << ex.what() << std::endl;
const char * ExceptionTpye = ex.what();
std::cout<<strlen(ExceptionTpye)<<endl;
}
spdlog::drop("console1");
return ;
}
UINT CMFCApplication1Dlg::Thread2(LPVOID pParam)
{
try{
//size_t q_size = 4096; //queue size must be power of 2
//spdlog::set_async_mode(q_size, spdlog::async_overflow_policy::block_retry);
auto console = spd::stdout_color_st("console2");
for (int i = ; i < ; i++){
Sleep();
DWORD dReturn = WaitForSingleObject(hEvent1, INFINITE);
if (WAIT_OBJECT_0 == dReturn)
{
console->info(" Event1 signaled ! ");
ResetEvent(hEvent1);
Sleep();
}
console->info("Thread 2,Count {}", i);
auto daily = spd::basic_logger_mt("basic2", "logs/basic-log.txt");
daily->info("Thread 2,Count {}", i);
spdlog::drop("basic2");
SetEvent(hEvent2);
}
}
catch (const spd::spdlog_ex& ex)
{
std::cout << "Thread 2 Logger failed: " << ex.what() << std::endl;
}
spdlog::drop("console2");
return ;
}
原理就是:先启动Event2,这样Thread1就可以执行,执行完第一个循环后把Event1置为有信号,Event2为无信号。这样处于等待状态的Thread2就可以执行了,Thread2执行第一个循环之后把Event2置位有信号,Event1置为无信号。
最后发现Thread1和Thread2交替执行!!!!这样子没什么意义吧。。。
放在cpp文件的开头定义为全局变量,输出在类的成员函数中执行,编译没问题,但运行时无输出。为何?
c++ 日志输出库 spdlog 简介(4)- 多线程txt输出日志的更多相关文章
- c++ 日志输出库 spdlog 简介(1)
参考文章: log库spdlog简介及使用 - 网络资源是无限的 - CSDN博客 http://blog.csdn.net/fengbingchun/article/details/78347105 ...
- c++日志输出库 spdlog 简介(3)多线程控制台输出日志
spdlog源码分析:https://www.cnblogs.com/eskylin/p/6483199.html spdlog的异步模式使得spdLog可以支持多线程,于是写了一个多线程的小例子: ...
- c++ 日志输出库 spdlog 简介(2)
继续上一篇,example.cpp解析. 1.set_pattern 自定义日志格式 官方参考:https://github.com/gabime/spdlog/wiki/3.-Custom-form ...
- 细说Java主流日志工具库
概述 在项目开发中,为了跟踪代码的运行情况,常常要使用日志来记录信息. 在Java世界,有很多的日志工具库来实现日志功能,避免了我们重复造轮子. 我们先来逐一了解一下主流日志工具. java.util ...
- 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)
前言: 本章介绍自己写的基于java.util.logging的轻量级日志记录库(baseLog). 该版本的日志记录库犹如其名,baseLog,是个实现日志记录基本功能的小库,适合小型项目使用,方便 ...
- zlog 纯C日志函数库的简单使用方法
zlog简述: log是一个高性能.线程安全.灵活.概念清晰的纯C日志函数库. 事实上,在C的世界里面没有特别好的日志函数库(就像JAVA里面的的log4j,或者C++的log4cxx).C程序员都喜 ...
- Java主流日志工具库
在项目开发中,为了跟踪代码的运行情况,常常要使用日志来记录信息.在Java世界,有很多的日志工具库来实现日志功能,避免了我们重复造轮子.我们先来逐一了解一下主流日志工具. 1.java.util.lo ...
- Log4j配置的经典总结,打印日志文件,日志存库
一.介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制 日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Sy ...
- 如何提升mysql replication的性能&多线程传输二进制日志
1,最好使用内网或者专线链路传输binlog数据 (千兆网卡.还不够的话,bounding 技术,扩展带宽) 在my.cnf中强制使用内网ip传输数据bind-address=ip2,将二进制保存在独 ...
随机推荐
- clipboard.js复制文字
A-固定内容: <script type="text/javascript" src="script/clipboard.min.js"></ ...
- 旋转链表(所有元素往右移) rotate list
[抄题]: 给定一个链表,旋转链表,使得每个节点向右移动k个位置,其中k是一个非负数 样例 给出链表1->2->3->4->5->null和k=2 返回4->5-& ...
- [leetcode]238. Product of Array Except Self除了自身以外的数组元素乘积
Given an array nums of n integers where n > 1, return an array output such that output[i] is equ ...
- 使用jdbc编程实现对数据库的操作以及jdbc问题总结
1.创建数据库名为mybatis. 2. 在数据库中建立两张表,user与orders表: (1)user表: (2)orders表: 3.创建工程 * 开发环境: * eclipse mars * ...
- How to add libraries to “External Libraries” in WebStorm/PhpStorm/Intellij
Stack Overflow Questions Developer Jobs Tags Users Log In Sign Up Join Stack Overflow to learn, sh ...
- jquery节点获取
jQuery.parent(expr) 找父亲节点,可以传入expr进行过滤,比如$("span").parent()或者$("span").parent(& ...
- 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)
传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...
- 2018.06.30 BZOJ4765: 普通计算姬(dfs序+分块+树状数组)
4765: 普通计算姬 Time Limit: 30 Sec Memory Limit: 256 MB Description "奋战三星期,造台计算机".小G响应号召,花了三小时 ...
- springboot问题,没有主清单属性
在pom.xml中添加 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins< ...
- java中线程和并发面试题
http://www.cnblogs.com/dolphin0520/p/3932934.html http://www.cnblogs.com/dolphin0520/p/3958019.html ...