C++2a(C++20)に向けて(PDF)P0053R6が採択され、マルチスレッド環境下でのストリーム出力排他制御をサポートする同期化出力ストリームstd::osyncstream
が追加される。
// C++2a(C++20) #include <syncstream> #include <iostream> void thread1(int value) { // 下記行の処理結果がアトミックにストリーム出力される std::osyncstream(std::cout) << "value=" << value << '\n'; } void thread2(int value) { // 同期化出力ストリームオブジェクトを作成 std::osyncstream syncout{std::cout}; syncout << "value=" << value << std::endl; syncout.emit(); // emit呼び出しでアトミックにストリーム出力される syncout << "double=" << (value * 2) << std::endl; // osyncstreamデストラクタにより暗黙にemitが呼び出される }
osyncstream
に対するフラッシュ操作(endl
やflush
マニピュレータ)のみでは、実際の標準出力(std::cout
)への出力が行われないことに注意。osyncstream
オブジェクトを破棄する(デストラクタ呼び出し)か、既定動作では明示的にemit
メンバ関数呼び出す必要がある。
別途提案されている(PDF)P0753R1が採択されれば、同期出力ストリーム専用マニピュレータによりフラッシュ操作時の自動emitやflash+emitを明示できるようになる。
2018-04-14追記:2018年4月会合において、C++2aに向けて(PDF)P0753R2が採択された。
// P0053R6 + P0753R1 void thread3(int value) { std::osyncstream syncout{std::cout}; // フラッシュ操作+emit呼び出しを明示 syncout << "value=" << value << '\n' << std::flush_emit; // フラッシュ操作で自動的にemitを呼び出すよう設定 syncout << std::emit_on_flush; // static_cast<syncbuf*>(syncout.rdbuf())->set_emit_on_sync(true);相当 syncout << "double=" << (value * 2) << std::endl; syncout << "half=" << (value / 2) << std::endl; }
関連URL