gpt4 book ai didi

c++ - 即使使用 strand,async_writes 的顺序也不正确

转载 作者:太空宇宙 更新时间:2023-11-04 16:00:18 25 4
gpt4 key购买 nike

我正在编写一个程序,将读取的数据转发给另一个对等点。我有一个在每次读取套接字上的数据后调用的方法。此方法将数据发布到一个链中以将其写回另一个对等点。当发送大块数据时,应用程序发回的数据与接收到的数据不一样,问题是数据不再是有序的。只有在 boost::asio::io_service 中使用多线程时才会出现这种情况。

handleGatewayReply 在套接字上读取某些数据时被调用。此时(1),在文件中写入数据后,可以看到数据仍然是有序的。之后,调用 postBackendReply 并且数据仍然是有序的(2)。但是在 SessionConnection::postReply 中,如果我将数据刷新到文件 (3),我可以看到数据不再被排序。我不明白为什么此时订单丢失,我尝试在 handleGatewayReply 和 postBackendReply 中使用一个链(如代码所示),但行为仍然相同。

抱歉,我无法提交一个最小的、完整的和可验证的示例,因为该错误太难发现,需要多线程转发大量数据。

  void Reply::handleGatewayReply(std::stringstream* stream)
{
// Flush data to file (1)
m_strand.post(std::bind([=]() {
postBackendReply(*stream);
delete stream;
}
}));

}

void Reply::postBackendReply(const std::stringstream& stream)
{
auto buffer = std::make_shared<Buffer>();
buffer->m_buffers.push_back(stream.str());
// Flush data to file (2)
auto connection = m_request->connection();
if (connection) {
// connection->postReply(buffer); // doesn't work either
m_strand.post(std::bind(&SessionConnection::postReply, connection,buffer));
}

}


void SessionConnection::postReply(BufferPtr buffer)
{
// Flush data to file (3)
m_ioService.post(
m_ostrand.wrap(
std::bind(&SessionConnection::sendNext,
shared_from_this(), buffer)));
}
}

最佳答案

当使用链时:

  1. 切勿将任何处理程序直接发布到 io_service - 这肯定会丢失顺序并破坏并发保证。

  2. strand::wrap 每个异步处理程序。

  3. 在(包装的)处理程序中,如果您需要强制执行命令,dispatch 到 strand。如果发布的处理程序在将来某个时间点执行时仍然有效,则只向它发布

例子:

thing.async_op(mystrand.wrap([self = shared_from_this()](auto&& error){
self->mystrand.dispatch(&must_be_done_now_A);
self->mystrand.post(&may_be_done_out_of_order_B);
self->mystrand.dispatch(&must_be_done_now_C);
});

执行顺序为:

  1. thing 的处理程序
  2. must_be_done_now_A
  3. must_be_done_now_C
  4. thing 的处理程序完成
  5. 在此期间进入 io_service 的任何其他内容
  6. may_be_done_out_of_order_B

关于c++ - 即使使用 strand,async_writes 的顺序也不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45939451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com