C+中的异步线程安全日志记录+; 我正在寻找一种在C++项目中实现异步和线程安全日志记录的方法,如果可能的话,只需要一个文件。我目前正在为任务使用cerr和clog,但由于它们是同步的,所以每次记录某些内容时执行都会短暂暂停。这是一个相对重图形的应用程序,所以这种事情很烦人
新的记录器应该使用异步I/O来消除这些暂停。线程安全性也是可取的,因为我打算很快添加一些基本的多线程C+中的异步线程安全日志记录+; 我正在寻找一种在C++项目中实现异步和线程安全日志记录的方法,如果可能的话,只需要一个文件。我目前正在为任务使用cerr和clog,但由于它们是同步的,所以每次记录某些内容时执行都会短暂暂停。这是一个相对重图形的应用程序,所以这种事情很烦人,c++,logging,asynchronous,thread-safety,C++,Logging,Asynchronous,Thread Safety,新的记录器应该使用异步I/O来消除这些暂停。线程安全性也是可取的,因为我打算很快添加一些基本的多线程 我曾考虑过一个线程一个文件的方法,但这似乎会让管理日志成为一场噩梦。有什么建议吗?这是非常可行和实用的。我怎么知道?我上一份工作就是这么写的。不幸的是(对我们来说),他们现在拥有代码::-)可悲的是,他们甚至不使用它 我打算在不久的将来编写一个开源版本。同时,我可以给你一些提示 I/O操纵器实际上只是函数名。您可以为自己的日志类实现它们,以便日志记录器与cout/cin兼容 操纵器函数可以标记操
我曾考虑过一个线程一个文件的方法,但这似乎会让管理日志成为一场噩梦。有什么建议吗?这是非常可行和实用的。我怎么知道?我上一份工作就是这么写的。不幸的是(对我们来说),他们现在拥有代码::-)可悲的是,他们甚至不使用它 我打算在不久的将来编写一个开源版本。同时,我可以给你一些提示
这本质上是线程兼容的,因为您使用的是队列。但是,您仍然希望在写入队列时提供一些类似互斥体的保护,以便给定的日志我认为正确的方法不是每个线程一个文件,而是每个文件一个线程。如果系统中的任何一个文件(或资源)只被一个线程访问,那么线程安全编程就变得容易多了
因此,为什么不让Logger成为一个专用线程(或者多个线程,每个文件一个线程,如果您在不同的文件中记录不同的内容),在所有其他线程中,写入日志会将消息放在适当的Logger线程中的输入队列中,在写入上一条消息后,该线程将访问该消息。它只需要一个互斥锁就可以在记录器读取事件时保护队列不添加事件,还需要一个condvar,以便记录器在队列为空时等待。您是否考虑过使用日志库 我最近发现,有几种可用的方法,这看起来真的很不可思议 它更像是一个前端记录器,您可以自定义使用哪个系统。例如,它可以与
ACE
或log4cxx
交互,而且似乎非常易于使用和配置。它的主要优点是使用类型安全操作符,这总是很好的
如果您只是想要一个裸骨日志库:
- 王牌
- log4c*
- Boost.Log
我应该注意到,C++中实现无锁队列是可能的,并且它们对于日志记录来说是很好的。
< P>我注意到了这1年的+旧线程。也许我写的异步记录器会引起人们的兴趣 G2log使用受保护的消息队列将日志条目转发给慢速磁盘访问的后台工作进程 我曾经尝试过使用无锁队列,它增加了日志调用的平均时间,但减少了最坏情况下的时间,但是我现在使用的是受保护队列,因为它是跨平台的。它在Windows/Visual Studio 2010和Ubuntu 11.10/gcc4.6上进行了测试它是作为公共域发布的,因此您可以随心所欲地使用它,而无需附加任何条件。我也有同样的问题,我相信我已经找到了完美的解决方案。我向您展示了一个名为loguru的单头库:
它易于使用、可移植、可配置、基于宏,并且默认情况下不包含任何内容(对于甜蜜、甜蜜的编译时间)。互斥锁难道不意味着如果一个线程已经在尝试写入,它必须旋转直到解锁吗?这有什么帮助?我当然不会延迟对象到流的转换。将它放入另一个线程意味着必须同步它。。。这很可能会痛得要命——不是旋转,而是阻挡。但是,如果您不进行字符串处理,则加载队列的时间间隔很短。字符串处理由日志线程完成@Matthieu,在加载队列时,实时处理字符串比任何互斥锁阻塞造成的伤害要大得多。我需要立即传递日志消息以进行异步写入,线程的任何等待都可能导致恼人的暂停,同样,异步执行字符串处理会导致所有记录对象上的线程安全问题,正确性先于性能,这里的问题不是队列阻塞,而是IO缓慢。您可以不使用带无锁队列的互斥锁而逃脱。不过,条件变量的区别要大得多。根据充电情况,你可能更喜欢旋转,而不是睡觉,然后被唤醒。这还取决于你是否有空闲的内核:)如果我们的系统中有忙的东西在等待,看门狗会杀死整个应用程序:)嗯,我不想引入任何这些。前两个看起来有些过分,后一个在审查中有很多性能问题,这是他们没有将其添加到Boost集合中的原因之一。如果日志记录不能导致任何阻塞,我通常会做的事情就是(例如,使用打印调试竞态条件..嘿,它很有效而且很简单!)就是使用一个线程本地消息队列来存储带有时间戳的令牌(在这种情况下,最好直接用异步IO输出)。如果您需要数据,您只需稍后对输出进行排序,这对于一般日志记录来说相当麻烦,但它的同步量是最低的:nil。重要的是,不仅要确保线程安全,而且要确保阻塞最小,而且要确保在sof