How to easily make std::cout thread-safe?(如何轻松使 std::cout 线程安全?)
问题描述
我有一个多线程应用程序,它大量使用 std::cout
进行日志记录而没有任何锁定.在这种情况下,如何轻松添加锁机制使 std::cout
成为线程安全的?
I have a multi-threaded application, which heavily uses std::cout
for logging without any locking. In such a case, how can I easily add lock mechanism to make std::cout
thread-safe?
我不想搜索每次出现的 std::cout
并添加一行锁定代码.太麻烦了.
I don't want to search for each occurrence of std::cout
and add a line of locking code. That is too tedious.
有什么更好的做法吗?
推荐答案
注意:这个答案是 pre-C++20 所以它不使用 std::osyncstream
具有单独的缓冲,但使用锁代替.
我猜您可以实现自己的类,该类包装 cout
并将互斥体与其关联.那个新类的 operator <<
会做三件事:
I guess you could implement your own class which wraps cout
and associates a mutex with it. The operator <<
of that new class would do three things:
- 为互斥锁创建一个锁,可能会阻塞其他线程
- 执行输出,即对包装的流和传递的参数执行操作符
<<
- 构造一个不同类的实例,将锁传递给那个
- create a lock for the mutex, possibly blocking other threads
- do the output, i.e. do the operator
<<
for the wrapped stream and the passed argument - construct an instance of a different class, passing the lock to that
这个不同的类将把锁和委托操作符 <<
保留到包装的流中.第二个类的析构函数最终会破坏锁并释放互斥锁.
This different class would keep the lock and delegate operator <<
to the wrapped stream. The destructor of that second class would eventually destroy the lock and release the mutex.
因此,您作为单个语句编写的任何输出,即作为 <<
调用的单个序列,只要您的所有输出通过具有相同互斥量的对象,就会自动打印.
So any output you write as a single statement, i.e. as a single sequence of <<
invocations, will be printed atomically as long as all your output goes through that object with the same mutex.
让我们调用两个类 synchronized_ostream
和 locked_ostream
.如果 sync_cout
是 synchronized_ostream
的一个实例,它包装了 std::cout
,那么序列
Let's call the two classes synchronized_ostream
and locked_ostream
. If sync_cout
is an instance of synchronized_ostream
which wraps std::cout
, then the sequence
sync_cout << "Hello, " << name << "!" << std::endl;
将导致以下操作:
synchronized_ostream::operator<<<
会获得锁synchronized_ostream::operator<<
会将Hello,"的打印委托给cout
operator<<(std::ostream&, const char*)
将打印Hello,"synchronized_ostream::operator<<
会构造一个locked_ostream
并将锁传递给那个locked_ostream::operator<<
会将name
的打印委托给cout
operator<<(std::ostream&, std::string)
将打印名称- 同样的委托给
cout
发生在感叹号和结束线操纵器 locked_ostream
临时被破坏,锁被释放
synchronized_ostream::operator<<
would aquire the locksynchronized_ostream::operator<<
would delegate the printing of "Hello, " tocout
operator<<(std::ostream&, const char*)
would print "Hello, "synchronized_ostream::operator<<
would construct alocked_ostream
and pass the lock to thatlocked_ostream::operator<<
would delegate the printing ofname
tocout
operator<<(std::ostream&, std::string)
would print the name- The same delegation to
cout
happens for the exclamation point and the endline manipulator - The
locked_ostream
temporary gets destructed, the lock is released
这篇关于如何轻松使 std::cout 线程安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何轻松使 std::cout 线程安全?
基础教程推荐
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 从 std::cin 读取密码 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01