避免cout线程不安全的一个做法
前言
std::cout
重载了<<
运算符,这使得写一些很短的代码时很方便。但是如果在多线程的条件下,cout并不是线程安全的。
举例
举个例子,我们创建5个线程
1 |
|
实际上,看样子好像控制台应该输出5行内容,但是运行结果可能是这样的
1 | msg1 msg2 msg3 thread_id = msg1 msg2 msg3 thread_id = 139926598575808139926606968512 |
这是因为cout在使用时可能会存在线程之间的打印信息乱串的问题,看一下编译器眼中我们这段程序中的cout是什么样的:
1 | std::operator<<(std::operator<<(std::operator<<(std::operator<<(std::operator<<(std::cout, "msg1"), " msg2"), " msg3"), " thread_id = "), std::this_thread::get_id()).operator<<(std::endl); |
可以看到,这不是通过单个 std::operator<<
调用完成的,也就是说这个操作并不是原子的
解决方法
- 使用
std::format
(C++20) - 使用第三方库,如
folly
,fmtlib
等 - 使用stringstream
- …
这里使用stringstream做个演示。将Test函数修改如下:
1 | std::stringstream ss; |
这样,控制台的输出就不会乱串了。