使用boost :: asio异步模型进行套接字读取,多个线程

时间:2016-01-13 22:04:30

标签: c++ multithreading sockets boost boost-asio

我有一个案例,我的app主线程(线程1)必须运行解锁。它需要通过套接字接收流数据......并且数据将随着时间的推移从远程服务器不断到达。我对线程1的控制有限(这是插件类型的软件到一个提供线程1的更大的主机应用程序)。

因此,我在线程1上调用一个指向缓冲区的指针来放置数据。如果套接字没有传入数据,我可以写零。需要至少X个字节的数据来填充给定的缓冲区I。如果套接字缓冲区中至少没有X字节(稍后会有更多内容),那么我再次用零填充它。

由于我对线程1的控制有限,我相信我必须有一个线程2来处理套接字接口(同意?)。假设我创建该线程并将其设置为类似boost :: asio async TCP server。专注于传入"阅读"在这个例子的一面,考虑这样的事情,我已经创造了一个无穷无尽的读者" (直到我杀死io_socket或线程2或其他一些)。

void do_read()
  {
    auto self(shared_from_this());
    socket_.async_read_some(boost::asio::buffer(data_, max_length),
        [this, self](boost::system::error_code ec, std::size_t length)
        {
          if (!ec)
          {
            do_read();
          }
        });
  }

它将数据堆积到data_中 - 缓冲区的简单静态数组。由于我不确切知道需要多少缓冲,因此我考虑使用矢量类型的实现。似乎提升这种方法的方法是使用boost :: asio :: streambuf - 它以FIFO方式调整大小并进行操作(这很重要,因为我希望我的输入数据保持有序)。它还具有输入序列和输出序列的概念。我的目标是使用这个...其中线程2将通过上面的代码将数据放入输出序列,并且线程1将在运行时从输入序列读取数据并发现它具有多于X个字节。从输出到输入的streambuf内部副本使用commit()完成。但我的理解是boost :: asio :: streambuf通常不是线程安全的。可以使用锁来解决对streambuf(输入或输出序列)的所有访问以解决问题,但是在套接字端...必须在async_read_some和do_read之间保持锁定,因为它在某些地方访问streambuf介于两者之间。我认为这将说明线程2将在"大部分时间",因此锁定在线程1上是非常有限的(并且线程1再次无法阻塞,因此它必须"尝试"锁定,很少得到它。)

似乎boost :: asio :: streambuf对于一个线程访问输出序列应该是安全的,而另一个线程正在访问输入序列(?)。我希望唯一的争论点是commit()。如果我控制了提交(并且我不清楚...我认为async_read可能会自动执行吗?)然后我就可以锁定提交。

有什么办法可以做我想做的事吗?不可否认,我可能过于专注于减少副本。如果我允许另一个副本,那么似乎可以在线程1和2之间创建另一个线程锁定缓冲区/队列(thread_buf)... do_read可以锁定,从streambuf复制到thread_buf,解锁,async_read等等。线程1会锁定,如果thread_buf有足够的数据将其复制出来,则解锁。

0 个答案:

没有答案