簡體   English   中英

來自多個線程的 std::cout

[英]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!
    }
}

更多信息: https://stackoverflow.com/a/22026764/13735754

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM