我理解为避免输出混合,多个线程对 cout 和 cerr 的访问必须同步。在同时使用 cout 和 cerr 的程序中,单独锁定它们是否足够?还是同时写入 cout 和 cerr 仍然不安全?
编辑说明:我知道 cout 和 cerr 在 C++11 中是“线程安全的”。我的问题是不同线程同时写入 cout 和写入 cerr 是否会像两次写入 cout 那样相互干扰(导致交错输入等)。
最佳答案
如果你执行这个函数:
void f() {
std::cout << "Hello, " << "world!\n";
}
从多个线程中,您将获得两个字符串的或多或少的随机交错,"Hello,"
和 "world\n"
。那是因为有两个函数调用,就好像你写了这样的代码:
void f() {
std::cout << "Hello, ";
std::cout << "world!\n";
}
为了防止交错,你必须加一把锁:
std::mutex mtx;
void f() {
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Hello, " << "world!\n";
}
也就是说,交织问题与cout
无关。这是关于使用它的代码:有两个单独的函数调用插入文本,所以除非你阻止多个线程同时执行相同的代码,否则函数调用之间有可能进行线程切换,这就是给你的交织。
请注意,互斥锁不会阻止线程切换。在前面的代码片段中,它阻止了从两个线程同时执行 f()
的内容;其中一个线程必须等到另一个线程完成。
如果您也写入cerr
,您会遇到同样的问题,并且您会得到交错的输出,除非您确保永远不会有两个线程进行这些操作inserter 函数同时调用,这意味着两个函数必须使用相同的互斥量:
std::mutex mtx;
void f() {
std::lock_guard<std::mutex> lock(mtx);
std::cout << "Hello, " << "world!\n";
}
void g() {
std::lock_guard<std::mutex> lock(mtx);
std::cerr << "Hello, " << "world!\n";
}
关于c++ - iostream线程安全,cout和cerr一定要分开加锁吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14637595/