首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C++、cin、cout、线程和sync_with_stdio损坏的输出

C++、cin、cout、线程和sync_with_stdio损坏的输出
EN

Stack Overflow用户
提问于 2012-12-23 10:12:30
回答 1查看 4K关注 0票数 11

我正试图在C++中制作一个程序,以最快的方式处理大量的数据包。所有来自标准的数据包都应尽可能快地读取,从一个池发送到一个线程进行处理,然后处理到一个输出线程,该输出线程将包写入标准输出。

在C++中使用标准输入和输出时,建议在任何输入或输出之前调用stdio(false)函数。在某些环境中,虽然在调用后应该避免使用标准的C函数进行输入/输出,但这会取得很大的加速效果。

嗯,这似乎在一条线上工作得很好。但是,正如我已经说过的,我的意图是使用一个线程作为输入,一个用于输出,多个线程用于并行处理。我观察到输出有一些问题。这是输出线程(非常简化):

代码语言:javascript
运行
复制
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),我会得到一个明显的加速,但是我的输出总是以某种方式损坏:

代码语言:javascript
运行
复制
Packet id = Packet id = 4
Packet id = 5
Packet id = 6
Packet id = 7
Packet id = 8
Packet id = 9
Packet id = 10

那么,问题在哪里?C++难道不能使用快速的标准输入/输出来执行多线程吗?

EN

Stack Overflow用户

回答已采纳

发布于 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非常容易

代码语言:javascript
运行
复制
std::ios_base::sync_with_stdio(false);

std::cin.tie(nullptr);
std::cerr.tie(nullptr);

或者如果编译器不支持C++11:

代码语言:javascript
运行
复制
std::ios_base::sync_with_stdio(false);

std::cin.tie(static_cast<ostream*>(0));
std::cerr.tie(static_cast<ostream*>(0));

随着这一变化,我的输出现在是正确的:

代码语言:javascript
运行
复制
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时进行刷新,所以它也更快:-)

票数 26
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14010147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档