This code when using osyncstream outputs garbage characters, isn't alway in sync, and seg faults. When output is to std::cout directly the output isn't in sync but output is good and does not seg fault.
#include <atomic>
#include <chrono>
#include <iostream>
#include <syncstream>
#include <thread>
std::osyncstream sync_out { std::cout };
//std::ostream& sync_out { std::cout };
void test_ths(int th) {
while(true) {
sync_out << "th " << th << " wait 1\n";
// std::this_thread::sleep_for(std::chrono::milliseconds(30 + 2 * th));
std::this_thread::sleep_for(std::chrono::milliseconds(30));
sync_out << "th " << th << " wait 2\n";
// std::this_thread::sleep_for(std::chrono::milliseconds(30 + 2 * th));
std::this_thread::sleep_for(std::chrono::milliseconds(30));
// needed to force output from osyncstream
sync_out.emit(); // comment out when using std::cout
}
}
int main() {
std::jthread t1([] {
test_ths(1);
});
std::jthread t2([] {
test_ths(2);
});
std::jthread t3([] {
test_ths(3);
});
std::jthread t4([] {
test_ths(4);
});
t1.join();
t2.join();
t3.join();
t4.join();
}
Sample output illustrating problems.
th 2 wait 1
th th 4 wait 2
3 wait 2
th 1 wait 2
th 2 wait 2
th t 1
th о�ޓ�F�ߓ�F�@FfW��,@���W�th 4 wait 1
th wait 1
th 2 wait 1
th 3 wait 2
th 4 wait 2
th 2 wait 2
th 3 wait 2
th 1 wait 2
th 2 wait 1
th 4 wait 1
th 3 wait 1
Segmentation fault (core dumped)
The problem is more pronounced when the sleep_for times are the same. The commented out lines introduce some jitter which helps but the problems still occur.
When std::cout is used, with sync_out.emit();
commented out, it runs okay.
My understanding of osyncstream is the output from different thread shouldn't intermingle, i.e. that is its purpose.
That's not how osyncstream
is supposed to be used. Every thread needs to construct its own osyncstream
; there is no synchronization on access to the osyncstream
itself. Only the transfer performed by emit
is synchronized, and then only with respect to the streambuf it wraps.
Having a global osyncstream
is therefore entirely pointless.