0

我正在使用 boost::asio::windows::stream_handle 并使用 async_read_some 方法从命名管道中递归读取数据。我为 async_read_some 方法关联了一个 read_handler。但是 async_read_some 处理程序只被调用一次,当新消息通过管道时它不会被进一步调用。通过反复试验方法,我将 read_handler 再次分配给 async_read_some 方法,现在它被正确调用了。但这是正确的做法,还是请提出一种从管道获得持续响应的优雅方式。

boost::asio::io_service my_io_service; 
boost::asio::windows::stream_handle pipe( my_io_service);
boost::array<char, 4096> buffer;

void CPublishSubscribeLib::read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred)
{
if(bytes_transferred > 0 )
pipe.async_read_some(boost::asio::buffer(buffer, 150), boost::bind(&CPublishSubscribeLib::read_handler, this, _1, _2));
}

谢谢是提前!

4

2 回答 2

1

使用 Boost.Asio,单个异步操作可能只调用一次关联的处理程序,然后立即删除 Boost.Asio 创建的处理程序的所有副本。因此,如果一个async_read_some操作只启动一次,那么ReadHandler将只被调用一次。通过从同一操作的处理程序中启动操作来形成异步链是一种非常常见的模式。在这种情况下,async_read_some从内部启动操作是正常的CPublishSubscribeLib::read_handler

于 2013-04-14T16:24:56.983 回答
0

为了回答您关于从管道获取连续数据流的正确方法的问题 - 当然,可以从内部调用 read_handler 来处理下一条消息。我在我的代码中这样做并且效果很好。要记住的重要一点是,您的 read_handler 所在的线程需要是响应式的。这意味着处理每条消息不应该花费太多时间。因此,许多人建议将消息​​简单地复制到缓冲区,然后将其存储在某种容器(队列、堆栈或向量)中保存消息,然后通知工作线程唤醒并处理消息。这是我在代码中采用的方法。但是,如果处理量很小和/或服务器没有发送很多消息,您可能不需要在代码中执行此操作。如果您在将小消息从套接字复制到缓冲区时担心性能和内存碎片,那么您可以考虑分配一个大的环绕缓冲区来存储消息 .vs。当每条消息从堆中到达时为其分配空间。

于 2013-04-14T16:15:48.363 回答