std::osyncstream 输出乱码导致段错误
std::osyncstream outputs garbled text and causes seg fault
此代码在使用 osyncstream 时输出垃圾字符,并不总是同步,并且出现段错误。当输出直接到 std::cout 时,输出不同步但输出良好并且没有出现故障。
#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();
}
说明问题的示例输出。
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)
当sleep_for次相同时问题更明显。注释掉的行引入了一些 jitter 这有帮助,但问题仍然存在。
使用std::cout时,注释掉sync_out.emit();
,运行正常。
我对 osyncstream 的理解是不同线程的输出不应该混合,也就是说,这就是它的目的。
osyncstream
不应该这样使用。每个线程都需要构造自己的osyncstream
;对 osyncstream
本身的访问没有同步。只有 emit
执行的传输是同步的,然后只与它包装的 streambuf 同步。
因此,拥有全局 osyncstream
完全没有意义。
此代码在使用 osyncstream 时输出垃圾字符,并不总是同步,并且出现段错误。当输出直接到 std::cout 时,输出不同步但输出良好并且没有出现故障。
#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();
}
说明问题的示例输出。
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)
当sleep_for次相同时问题更明显。注释掉的行引入了一些 jitter 这有帮助,但问题仍然存在。
使用std::cout时,注释掉sync_out.emit();
,运行正常。
我对 osyncstream 的理解是不同线程的输出不应该混合,也就是说,这就是它的目的。
osyncstream
不应该这样使用。每个线程都需要构造自己的osyncstream
;对 osyncstream
本身的访问没有同步。只有 emit
执行的传输是同步的,然后只与它包装的 streambuf 同步。
因此,拥有全局 osyncstream
完全没有意义。