本文作者:StubbornHuang
版权声明:本文为站长原创文章,如果转载请注明原文链接!
原文标题:C++ – 线程安全的std::cout
原文链接:https://www.stubbornhuang.com/1129/
发布于:2021年02月01日 11:35:05
修改于:2021年02月01日 13:06:02

1 线程安全的std::cout
最近在多个子线程中使用std::cout输出日志信息发现std::cout不是线程安全的,无法保持线程同步,导致日志信息无法按照固定顺序输出,现象如下:

所以对std::cout做了一个封装以保证多线程之间的同步,代码如下:
#include <iostream>
#include <string>
#include <mutex>
namespace ThreadSafePrint
{
static std::mutex m_CoutMutex;
struct cout
{
std::unique_lock<std::mutex> m_Lock;
cout():
m_Lock(std::unique_lock<std::mutex>(m_CoutMutex))
{
}
template<typename T>
cout& operator<<(const T& message)
{
std::cout << message;
return *this;
}
cout& operator<<(std::ostream& (*fp)(std::ostream&))
{
std::cout << fp;
return *this;
}
};
}
调用示例:
ThreadSafePrint::cout() << "Hello World" << std::endl;
测试程序如下:
#include <iostream>
#include <string>
#include <mutex>
#include <thread>
namespace ThreadSafePrint
{
static std::mutex m_CoutMutex;
struct cout
{
std::unique_lock<std::mutex> m_Lock;
cout():
m_Lock(std::unique_lock<std::mutex>(m_CoutMutex))
{
}
template<typename T>
cout& operator<<(const T& message)
{
std::cout << message;
return *this;
}
cout& operator<<(std::ostream& (*fp)(std::ostream&))
{
std::cout << fp;
return *this;
}
};
}
void Thread1()
{
for (int i=0;i<10000;++i)
{
ThreadSafePrint::cout() <<std::this_thread::get_id() <<" : aa" << std::endl;
//std::cout << std::this_thread::get_id() << " : aa" << std::endl;
}
}
void Thread2()
{
for (int i = 0; i < 10000; ++i)
{
ThreadSafePrint::cout() << std::this_thread::get_id() << " : bb" << std::endl;
//std::cout << std::this_thread::get_id() << " : bb" << std::endl;
}
}
void Thread3()
{
for (int i = 0; i < 10000; ++i)
{
ThreadSafePrint::cout() << std::this_thread::get_id() << " : cc" << std::endl;
//std::cout << std::this_thread::get_id() << " : cc" << std::endl;
}
}
int main()
{
std::thread printThread1(Thread1);
std::thread printThread2(Thread2);
std::thread printThread3(Thread3);
printThread1.join();
printThread2.join();
printThread3.join();
getchar();
return 0;
}
当前分类随机文章推荐
- C++ 11 - final关键字简要介绍 阅读1757次,点赞0次
- C++ - C++类的特殊成员函数,析构函数,拷贝构造函数,移动构造函数,赋值运算符,移动赋值运算符介绍和基础语法 阅读647次,点赞0次
- C++ – UTF8编码下的全角字符转半角字符 阅读1418次,点赞0次
- C++11/std::thread - 线程的基本用法 阅读3083次,点赞0次
- C++ - 随机洗牌算法,std::random_shuffle和std::shuffle 阅读1068次,点赞1次
- GCC/GG++中编译优化选项-O -O0 -O1 -O2 -O3 -Os -Ofast -Og -Oz各自的区别和作用 阅读2375次,点赞2次
- C++ - 在CTC解码算法后移除相邻重复和blank索引 阅读113次,点赞0次
- C++STL容器 - std::map容器修改、元素操作总结 clear,insert,emplace,erase,swap,merge,extract,insert_or_assign等 阅读1092次,点赞0次
- C++ - 判断本机文件是否存在的方式总结 阅读4134次,点赞0次
- C++ - 一文搞懂std::future、std::promise、std::packaged_task、std::async的使用和相互区别 阅读37次,点赞0次
全站随机文章推荐
- 资源分享 - Jim Blinn's Corner - A Trip Down the Graphics Pipeline 英文高清PDF下载 阅读2540次,点赞3次
- Python - BeautifulSoup的find()和findAll() 阅读2608次,点赞0次
- WordPress - 修复Markdown编辑器插件WP-Editor.md在插入php代码块后代码中的$符号无法正常显示的问题 阅读1015次,点赞0次
- FFmpeg - 录制HLS直播流为mp4文件 阅读657次,点赞0次
- 资源分享 – OpenGL SuperBible - Comprehensive Tutorial and Reference (Sixth Edition) OpenGL蓝宝书第6版英文高清PDF下载 阅读1638次,点赞0次
- 资源分享 - Game Development Tools 英文高清PDF下载 阅读1733次,点赞0次
- C++ - std::numeric_limits
简介与使用,用于获取指定数据类型的最大值与最小值 阅读67次,点赞0次 - 书籍翻译 - Cloth Simulation for Computer Graphics 中文翻译 阅读354次,点赞0次
- Python - 读取视频为numpy数组以及将numpy数组转换为视频 阅读1038次,点赞0次
- 左右手坐标系与旋转正向 阅读6847次,点赞1次
评论
164