【发布时间】:2020-10-02 11:20:06
【问题描述】:
我有一个应用程序,我在并行工作线程中执行昂贵的计算。为简单起见,我直接从这些线程将结果写入标准输出。
这一直很好,直到我改变了一些东西以使代码运行得更快。首先,我将 std::endl 替换为 "\n" 以防止在每一行之后刷新。我在主程序的 init 部分添加了以下几行:
std::cin.tie(nullptr);
std::ios_base::sync_with_stdio(false);
工作线程代码的基本结构如下:
while(true) {
// get data from job queue, protected by unique_lock on std::mutex
// process the data
// print results
{
std::lock_guard<std::mutex> lk(outputMutex_);
std::cout << "print many results" << "\n"; // was originally std::endl
}
}
由于这种“优化”,工人的输出偶尔会“混合”。即互斥锁没有达到预期目的。
为什么会这样?我的理解是只有一个 stdout 流缓冲区,并且数据按顺序到达相应的缓冲区,即使在释放互斥锁之前没有从该缓冲区刷新输出。不过好像不是这样的……
(我意识到在单独的线程中生成输出可能会更好,但是我需要使用另一个队列将这些结果传回,这在这里似乎没有必要)
更新:可能我的帖子不够清晰。我不关心结果的顺序。问题是(对于上面的例子)而不是这个:
print many results
print many results
print many results
我有时会:
print many print many results
results
print many results
并且 outputMutex_ 是一个静态成员,由所有工作线程共享。
【问题讨论】:
-
您正在进行修改同一资源的未排序调用。结果是,iirc,未定义,所以它没有区别,\n 或 std::endl。
-
这能回答你的问题吗? Synchronizing STD cout output multi-thread
-
@bipll:我不担心结果的顺序,但是尽管受到互斥锁的保护,结果并未作为实体打印
-
@underscore-d:不,不是真的。我的输出应该受到互斥锁的保护,并且我想避免将这些简单结果移动到单独的“输出”线程的开销,这也需要同步。
-
问题中的代码sn-ps应该可以正常工作,所以问题一定出在未显示的代码中。
标签: c++ multithreading c++17 stdout mutex