c++ - iostream线程安全,cout和cerr一定要分开加锁吗?

标签 c++ thread-safety cout

我理解为避免输出混合,多个线程对 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/

相关文章:

c++ - 错误 LINK2005 已在 Main.obj 中定义

javascript - 将字符串参数从 node.js 传递到 C++ 代码(使用 SWIG)

c++ - 构造函数在 C++ 和/或 C++11 中是线程安全的吗?

php, "thread safe"SQL操作

java - 屏幕关闭/打开后,同步(和 volatile )无法按预期工作

java - 浮点错误

c++ - 这是shell排序还是插入排序?

c++ - C++ 中一直存在纯虚方法吗?

c++ - 打印出 std::string

c++ - wcout 是如何工作的?