我终于找到了罪魁祸首。如果您搜索互联网,很多网站都建议使用sync_with_stdio 调用,但他们不讨论线程。
其他站点讨论 iostreams 和线程,例如this one https://stackoverflow.com/questions/6374264/is-cout-synchronized-thread-safe,但这并不能解释为什么我在使用 std::cin 时输出损坏只有一个线程和 std::cout也在它自己的线程中.
问题在于,在内部, std::cin 输入线程正在调用 std::cout 来刷新其缓冲区,但由于流未与互斥体或类似的东西同步,因此输出已损坏。如果缓冲区正在做不同的事情,为什么我应该同步它们?为什么 std::cin 会搞乱 std::cout ?
在 C++ 中,默认情况下,标准流 cin、cerr 和 clog 与 cout 绑定。这是什么意思?这意味着当您尝试从 cin 读取数据时,它首先会强制刷新 cout。有时这是有用的,你可以阅读here https://stackoverflow.com/questions/2704752/flushing-of-cout-prior-to-reading-input-using-cin-why.
但就我而言,这引起了一些严重的问题,那么,如何解开流呢?使用起来非常简单领带法 http://en.cppreference.com/w/cpp/io/basic_ios/tie:
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cerr.tie(nullptr);
或者,如果您的编译器不支持 C++11:
std::ios_base::sync_with_stdio(false);
std::cin.tie(static_cast<ostream*>(0));
std::cerr.tie(static_cast<ostream*>(0));
通过此更改,我的输出现在是正确的:
Packet id = 1
Packet id = 2
Packet id = 3
Packet id = 4
Packet id = 5
Packet id = 6
Packet id = 7
Packet id = 8
Packet id = 9
Packet id = 10
而且由于它避免了每次使用 std::cin 时都进行刷新,因此速度也更快:-)