我想知道一個std::osyncstream物件如何防止資料競爭條件?它會鎖定一些互斥鎖嗎?
我專門談論以下程式:
#include <iostream>
#include <fstream>
#include <thread>
#include <syncstream>
void worker( const std::size_t startValue, const std::size_t stopValue, std::ostream& os )
{
for ( auto idx { startValue }; idx < stopValue; idx )
{
std::osyncstream out { os };
out << "thread: " << std::this_thread::get_id( ) << "; work: " << idx << '\n';
}
}
void runThreads( std::ostream& os )
{
std::jthread t1 { worker, 10000, 20000, std::ref( os ) };
std::jthread t2 { worker, 20000, 30000, std::ref( os ) };
}
int main( )
{
std::ofstream file { "out.txt" };
runThreads( file );
}
上述代碼的來源可以在這里查看。雖然我做了一些細微的修改以使其更好更安全。
這個簡單的程式將 20,000 行列印到一個檔案中,而不會產生混亂的輸出。
可能的輸出:
thread: 2; work: 10000
thread: 3; work: 20000
thread: 2; work: 10001
thread: 2; work: 10002
thread: 2; work: 10003
thread: 2; work: 10004
thread: 2; work: 10005
thread: 2; work: 10006
.
.
.
幕后發生了什么?這兩個執行緒如何相互通信?他們有單獨的syncstream物件副本嗎?這個物件(即out)如何管理輸出流os?
uj5u.com熱心網友回復:
它會鎖定一些互斥鎖嗎?
是的,間接的。該類std::basic_osyncstream是osyncstream形式的特化basic_osyncstream<char>,派生自std::basic_ostream并且通常只有std::basic_syncbuf該類的一個“額外”成員。從 cppreference:
std::basic_osyncstream 的典型實作只包含一個成員:包裝的 std::basic_syncbuf。
正是該basic_syncbuf物件實作了輸出同步,防止了資料競爭。同樣,來自 cppreference(加粗我的):
std::basic_syncbuf 的典型實作持有一個指向包裝的 std::basic_streambuf 的指標,一個布爾標志,指示緩沖區是否將在同步(重繪 )時將其內容傳輸到包裝的緩沖區,一個布爾標志,指示當策略是掛起的重繪 時同步時不發出,使用分配器的內部緩沖區(例如 std::string),以及一個指向互斥鎖的指標,該互斥鎖用于在訪問同一包裝流緩沖區的多個執行緒之間同步發出 (這些互斥鎖可能位于哈希映射中指向用作鍵的 basic_streambuf 物件的指標)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/422763.html
標籤:
