[英]std::cout from multiple threads
我有一個應用程序,在其中我在並行工作線程中執行昂貴的計算。 為簡單起見,我直接從這些線程將結果寫入標准輸出。
這工作得很好,直到我改變了一些東西以使代碼運行得更快。 首先,我將 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
}
}
由於這個“優化”,工人的output偶爾會“混雜”。 即互斥鎖不符合其預期目的。
為什么會這樣? 我的理解是,只有一個標准輸出 stream 緩沖區,並且數據按順序到達相應的緩沖區,即使 output 在釋放互斥鎖之前沒有從該緩沖區中刷新。 但這似乎並非如此……
(我意識到在單獨的線程中生成 output 可能會更好,但是我需要使用另一個隊列傳回這些結果,這在這里似乎沒有必要)
更新:也許我的帖子不夠清楚。 我不關心結果的順序。 問題是(對於上面的例子)而不是這個:
print many results
print many results
print many results
我有時會得到:
print many print many results
results
print many results
並且 outputMutex_ 是所有工作線程共享的 static 成員。
您正在通過多個線程訪問 cout 。 對其隊列的訪問受到互斥鎖的保護,但需要刷新。 這不會自動發生(至少總是:))
std::endl
刷新 cout,' \n'
沒有
或者,您可以使用std::flush
告訴 cout 刷新:
https://en.cppreference.com/w/cpp/io/manip/flush
嘗試:
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"; // not flushed
std::cout << std::flush; // flushed!
std::cout << "print something else" << std::endl; // flushed!
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.