用于 C++ 的基于行的线程安全 std::cerr;
创建我自己的 std::cerr 以便它是逐行线程安全的最简单方法是什么。
我最好寻找代码来做到这一点。
我需要的是,一个线程生成的一行输出
(以std::endl
终止)在以下情况下保持作为一行输出
我实际上在我的控制台上看到它(并且没有与其他线程的输出混合)。
解决方案:std::cerr
比 cstdio 慢很多。我更喜欢在 CriticalSectionLocker
类中使用 fprintf(stderr, "The message")
,该类的构造函数获取线程安全锁,析构函数释放它。
What is the easiest way to create my own std::cerr
so that it is line-by-line thread-safe.
I am preferably looking for the code to do it.
What I need is so that a line of output
(terminated with std::endl
) generated by one thread stays as a line of output
when I actually see it on my console (and is not mixed with some other thread's output).
Solution: std::cerr
is much slower than cstdio. I prefer using fprintf(stderr, "The message")
inside of a CriticalSectionLocker
class whose constructor acquires a thread-safe lock and the destructor releases it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果可用, osyncstream (C++20) 可以解决此问题:
如果上述功能不可用,这里是一个嵌入式头文件,其中包含两个宏,用于线程安全写入
std::cout
和std::cerr
(它们必须共享一个互斥以避免输出交错)。这些基于两个其他答案,但我做了一些更改,以便轻松放入现有的代码库中。这适用于 C++11 及更高版本。我在 4 核处理器上使用 4 个线程对此进行了测试,每个线程每秒向
tout
写入 25,000 行,偶尔输出到terr
,它解决了输出问题交错问题。与基于结构的解决方案不同,当放入此头文件时,我的应用程序没有明显的性能下降。我能想到的唯一缺点是,由于这依赖于宏,因此不能将它们放入命名空间中。threadstream.h
test.cc
编译
输出
If available, osyncstream (C++20) solves this problem:
If the above feature is not available, here is a drop-in header file containing two macros for thread-safe writing to
std::cout
andstd::cerr
(which must share a mutex in order to avoid interleaving of output). These are based on two other answers, but I have made some changes to make it easy to drop into an existing code base. This works with C++11 and forward.I've tested this with 4 threads on a 4-core processor, with each thread writing 25,000 lines per second to
tout
and occasional output toterr
, and it solves the output interleaving problem. Unlike a struct-based solution, there was no measurable performance hit for my application when dropping in this header file. The only drawback I can think of is that since this relies on macros, they can't be placed into a namespace.threadstream.h
test.cc
compiling
output
这是我在某个时候编写的基于线程安全行的日志记录解决方案。它使用 boost mutex 来保证线程安全。它比必要的稍微复杂一些,因为您可以插入输出策略(它应该转到文件、stderr 还是其他地方?):
logger.h:
用法如下所示:
注意缺少
'\n '
和std::endl
因为它是隐式的。内容被缓冲,然后使用模板指定的策略自动输出。此实现还在该行前面添加了时间戳,因为它用于记录目的。no_output
策略是严格可选的,当我想禁用日志记录时我会使用它。Here's a thread safe line based logging solution I cooked up at some point. It uses boost mutex for thread safety. It is slightly more complicated than necessary because you can plug in output policies (should it go to a file, stderr, or somewhere else?):
logger.h:
Usage looks like this:
note the lack of a
'\n'
andstd::endl
since it's implicit. The contents are buffered and then atomically output using the template specified policy. This implementation also prepends the line with a timestamp since it is for logging purposes. Theno_output
policy is stricly optional, it's what I use when I want to disable logging.这:
适用于大多数编译器,适用于常见情况
myerr("ERR: " << message << number)
。This:
works on most compilers for the common case of
myerr("ERR: " << message << number)
.为什么不直接创建一个锁定类并在您想要执行线程安全 IO 的任何地方使用它呢?
然后你将任何你想要的 IO 放入一个块中:
变成:
Why not just create a locking class and use it where ever you want to do thread-safe IO?
Then you put any IO you want in a block:
becomes:
对 unixman 评论中的方法的改进(这并不真正适合评论)。
就可以使用它
如果仔细实现 ErrCriticalSectionLocker,
。但是,我个人更喜欢肯的建议。
An improvement (that doesn't really fit in a comment) on the approach in unixman's comment.
Which can be used like
if ErrCriticalSectionLocker is implemented carefully.
But, I would personally prefer Ken's suggestion.