【发布时间】:2017-08-16 13:35:12
【问题描述】:
我正在尝试将即发即弃 UDP 发送功能的实现从同步更改为异步。
当前简化的同步函数如下所示:
ssize_t UDPTransport::send_to(const char * buffer, size_t bufferSize) {
return mPSocket->send_to(boost::asio::buffer(buffer, bufferSize), mOutputEndpoint);
}
我已经设置了thread_group,并且设置了io_service::run() 来使用它。但是,问题是我无法保证在此调用完成后buffer 将存在。我需要存储缓冲区的内容,然后知道它什么时候空闲,以便我以后可以重新使用它或删除它。以下内容很简单,但如果我触发两个 send_to 调用,那么我无法保证 handle_send 会以相同的顺序被调用,我可能会 pop 仍然需要一些东西!
ssize_t UDPTransport::send_to(const char * buffer, size_t bufferSize) {
boost::asio::mutable_buffer b1 = boost::asio::buffer(buffer,bufferSize);
mMutex.lock();
mQueue.push(b1);
mPSocket->async_send_to(mQueue.back(), mOutputEndpoint,
boost::bind(&UDPTransport::handle_send, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
mMutex.unlock();
return bufferSize;
}
void UDPTransport::handle_send(const boost::system::error_code& error,
std::size_t bytes_transferred)
{
mMutex.lock();
mQueue.pop();
mMutex.unlock();
}
存储异步缓冲区,然后在不再需要时清理它的好方法是什么?
Reading online下面可能有一个更简单的方法,但我不知道我是否相信它。为什么共享指针会决定在调用处理程序之前不释放自己?
ssize_t UDPTransport::send_to(const char * buffer, size_t bufferSize)
{
auto buf = std::make_shared<std::string>(buffer, bufferSize);
mPSocket->async_send_to(boost::asio::buffer(*buf), mOutputEndpoint,
boost::bind(&UDPTransport::handle_send, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
return bufferSize;
}
【问题讨论】:
-
您链接的 shared_ptr 解决方案可能是正确的,因为它在 lambda 中按值捕获 shared_ptr。因此,一旦调用了处理程序,它就应该自行释放。但是你的 shared_ptr 代码并没有这样做。
标签: c++ sockets boost boost-asio