c++, cin, cout, threads和sync_with_stdio的输出损坏
Corrupted output with C++, cin, cout, threads and sync_with_stdio
我正试图在c++中制作一个程序,以最快的方式处理大量数据包。应该尽可能快地读取所有来自标准的数据包,将其发送给池中的一个线程进行处理,然后将其处理给输出线程,该线程将数据包写入标准输出。
当您使用c++中的标准输入和输出时,建议在任何输入或输出之前调用std::ios_base::sync_with_stdio(false)函数。在某些环境中,这可以实现很大的加速,尽管您应该避免在调用之后使用标准的C函数进行输入/输出。
嗯,这似乎在一个线程中完美地工作。但是正如我所说的,我的意图是使用一个线程进行输入,一个线程进行输出,多个线程进行并行处理。我观察到输出有一些问题。这是输出线程(非常简化):
void PacketDispatcher::thread_process_output(OutputQueue& output_queue) {
std::vector<Packet> packet_list;
while(output_queue.get(packet_list)) {
for (const auto& packet: packet_list) {
std::cout << "Packet id = " << packet.id << "n";
}
}
std::cout.flush();
}
如果我使用std::endl而不是"n",则损坏较少,但是std::endl强制刷新流,在这种情况下影响性能(并且问题没有解决,只是最小化了)。
这是程序中使用std::cout的唯一一点,但是如果我在程序开始时调用std::ios_base::sync_with_stdio(false),我得到了明显的加速,但我的输出总是以某种方式损坏:
Packet id = Packet id = 4
Packet id = 5
Packet id = 6
Packet id = 7
Packet id = 8
Packet id = 9
Packet id = 10
那么,问题在哪里?难道c++不能使用快速的标准输入/输出来实现多线程吗?
我终于找到了罪魁祸首。如果你在网上搜索,很多网站推荐使用sync_with_stdio调用,但是他们不讨论线程。
其他网站讨论iostreams和线程,比如这个,但这并不能解释为什么当我在中只使用一个线程中的std::cin,以及在它自己的线程中也使用std::cout 时,我的输出会损坏。 问题是,在内部,std::cin输入线程调用std::cout来刷新它的缓冲区,但是由于流没有与互斥锁或类似的东西同步,输出被破坏了。如果缓冲区在做不同的事情,我为什么要同步它们呢?为什么std::cin会干扰std::cout? 在c++中,默认情况下,标准流cin、cerr和clog与cout绑定。这是什么意思?这意味着当您尝试从cin中读取时,首先它将强制flush到cout。有时这是一些有用的东西,你可以在这里读到。 但在我的情况下,这引起了一些严重的问题,所以,如何解开流?使用方法非常简单: 或者如果你的编译器不支持c++ 11: 这改变了我的输出,现在是正确的: 并且由于它避免了每次使用std::cin时进行刷新,所以它也更快:-)std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cerr.tie(nullptr);
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
- Problems with std::cin.fail()
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- 与 stdio 同步是否使程序 I/O 非交互式?
- 这对"With a stackless coroutine, only the top-level routine may be suspended."意味着什么
- Boost.TEST with CLion: "Test framework quit unexpectedly"
- 避免碎片化的ClientHellos with OpenSSL (DTLS)
- Issues with Win32 ReadProcessMemory API
- Qt with WinAPI MouseProc
- [[maybe_unused]] with structured_binding?
- Issue with WriteProcessMemory
- OpenCV RTP-Stream with FFMPEG
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- std::adjacent_difference with std::chrono time_point
- 从macOS Catalina上的源代码编译LLVM(如何解决未找到"stdio.h")
- DLL Made with CMake 使程序崩溃
- QtCreator with C 库中的链接器问题
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- specialized std::default_delete with QQmlComponent
- VS2019 - Sudo Remote Debugging on Linux with Cmake project
- Inference pytorch C++ with alexnet and cv::imread image