bool emit();
概要
格納されている文字データを、ラップされたストリームに転送する。このような転送は、同じストリームを持つ他のbasic_syncbuf
オブジェクトによる転送に関してアトミックである。
効果
保留中の出力をラップされたストリームにアトミックに転送する。出力は、連続した文字の並びとして出力ストリームに現れる。
また、最後にemit()
が呼び出されてからsync()
が呼び出されている場合、ラップされたストリームに対してpubsync()
を呼び出してフラッシュも行う。
戻り値
以下の条件がすべて満たされる場合はtrue
、そうでない場合はfalse
を返す。
- ラップされたストリームが存在する。(ラップされたストリームへのポインタが
nullptr
でない。) - 保留中の出力内のすべての文字は正常に転送された。
- 要求されている場合、ラップされたストリームに対する
pubsync()
の呼び出しは成功した。
事後条件
成功すると、書き込まれた文字データは空になる。
同期
同じストリームバッファオブジェクトに文字を転送するすべてのemit()
呼び出しは、「happens before」関係と一致する全順序で実行されるように見える。各emit()
呼び出しは、その全順序で後続のemit()
呼び出しと同期する。実際には、これは下記の備考にあることを意味する。
注:ここでは、happens before 関係は全順序関係になっていると考えられる。また、modification order と矛盾しないとも考えられる。下記の参照を参照のこと。
備考
ラップされたストリームに一意に関連付けられたロックを保持しながら、ラップされたストリームのメンバ関数を呼び出すことができる。つまり、同じストリームを持つ他のbasic_syncbuf
オブジェクトに対してアトミックに転送することができる。
例
#include <iostream>
#include <syncstream>
#include <thread>
void thread1()
{
std::osyncstream bout{std::cout};
bout << "Hello, World!\n";
bout.emit(); // 通常 std::basic_osyncstream から呼ばれる。
// 文字が転送される。
}
void thread2()
{
// 同じバッファに行われる出力は、異なる std::basic_osyncstream(std::basic_syncbuf) の
// インスタンスからでも、アトミックに出力されることが保証される
std::osyncstream(std::cout) << "Goodbye, " << "Planet!" << '\n';
}
int main()
{
std::thread th1(thread1);
std::thread th2(thread2);
th1.join();
th2.join();
}
xxxxxxxxxx
#include <iostream>
#include <syncstream>
#include <thread>
void thread1()
{
std::osyncstream bout{std::cout};
bout << "Hello, World!\n";
bout.emit(); // 通常 std::basic_osyncstream から呼ばれる。
// 文字が転送される。
}
void thread2()
{
// 同じバッファに行われる出力は、異なる std::basic_osyncstream(std::basic_syncbuf) の
// インスタンスからでも、アトミックに出力されることが保証される
std::osyncstream(std::cout) << "Goodbye, " << "Planet!" << '\n';
}
int main()
{
std::thread th1(thread1);
std::thread th2(thread2);
th1.join();
th2.join();
}
出力例
thread1 の処理が先行した場合。ただし、各出力は連続したシーケンスとなるように、アトミックに行われることが保証される。
Hello, World!
Goodbye, Planet!
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: 11.1 ✅
- Visual C++: 2019 update 10 ✅