【问题标题】:Is it possible to fan-out an istream to multiple readers?是否可以将 istream 扇出给多个读者?
【发布时间】:2017-06-17 08:47:59
【问题描述】:

我有一个std::istream 可以使用。是否有可能以某种方式将其传递给可能会从不同位置寻找和阅读的多个阅读器?

如果不是,如果我将其限制为std::ifstream 的情况怎么办?

【问题讨论】:

  • 我认为流是不可复制的。所以传递相同流对象的想法是不可行的。
  • 我不知道 range-v3 是否带有这样的功能,但我想为InputRange 写一个像这样的好范围函数也不会太糟糕。如果不出意外,懒惰地循环输入并返回一系列输出副本([1,2,3] -> [[1,2,3], [1,2,3], [1,2,3] ]),数量由参数确定。不幸的是,这种直截了当的解决方案可能并不适合寻求。
  • 在同一个std::istream 的多个位置进行搜索将覆盖其他搜索。如果它是一个文件,您可能会为同一个文件打开多个 std::ifstreams 并寻找不同的位置;操作系统可能会为您优化访问。

标签: c++ c++11 istream


【解决方案1】:

您已经回答了您的问题。如果是文件流(ifstream),您将获得随机访问(只读;您可以设置打开模式),通过为一个线程打开多个 ifstream 来访问同一个文件的多个线程应该没有问题。 C++ 标准没有提及 ifstream 的线程安全性。对于通用 istream(socket、cin),如果您使用 get() 方法,您将使用输入流。我没有看到任何关于 istream 线程安全的文档。 peek() 方法不会消耗输入流,但仍会更改 istream 的内部状态。如果多个线程在同一个 istream 上执行 seek(),则行为未定义。 C++ 语言不保证内部锁。 seek() 基本上是取消引用某种指向内部缓冲区的指针。

我建议您让一个线程将 istream 读取到某个缓冲区(构造对象(生产者)或简单的原始内存),然后,多个线程可以消费结果(消费者)。这是典型的消费者/生产者同步;任何多线程教科书都会教你怎么做。

【讨论】:

  • 不同线程在seek时会互相干扰,不管流类型如何。 fstream 也不例外。
  • 那么解决方案应该是单线程读取,多线程消费,典型的消费者/生产者模型,你必须围绕 istream 进行包装。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-17
  • 2019-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-12
  • 2020-10-01
相关资源
最近更新 更多