我正试图在C++中制作一个程序,以最快的方式处理大量的数据包。所有来自标准的数据包都应尽可能快地读取,从一个池发送到一个线程进行处理,然后处理到一个输出线程,该输出线程将包写入标准输出。
在C++中使用标准输入和输出时,建议在任何输入或输出之前调用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的唯一一点,但是如果我在程序请求时调用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++难道不能使用快速的标准输入/输出来执行多线程吗?
发布于 2012-12-23 10:12:30
我终于找到凶手了。如果你搜索互联网,很多网站建议使用sync_with_stdio调用,但他们不谈论线程。
其他站点讨论了iostreams和线程,比如this one,但这并不能解释为什么我在中使用std::cin时只有一个线程,而std::cout 在它自己的线程中也是。
问题是,在内部,std::cin输入线程调用std::cout来刷新它的缓冲区,但是由于没有与互斥或类似的流同步,输出被破坏了。如果缓冲区在做不同的事情,我为什么要同步它们?为什么性病:cin在捣乱std::cout?
在C++中,默认情况下,标准流cin、cerr和clog绑定到cout。这是什么意思?这意味着,当你试图阅读cin,首先,它将迫使同花顺的cout。有时,这是有用的东西,因为你可以阅读here。
但是在我的例子中,这引起了一些严重的问题,那么,如何解开这些溪流呢?使用tie method非常容易
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时进行刷新,所以它也更快:-)
https://stackoverflow.com/questions/14010147
复制相似问题