gpt4 book ai didi

c++ - boost::asio 异步操作和资源

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:44 25 4
gpt4 key购买 nike

所以我制作了一个使用 boost::asio 库进行异步读写的套接字类。它有效,但我有几个问题。

这是一个基本的代码示例:

class Socket
{
public:
void doRead()
{
m_sock->async_receive_from(boost::asio::buffer(m_recvBuffer), m_from, boost::bind(&Socket::handleRecv, this, boost::asio::placeholders::error(), boost::asio::placeholders::bytes_transferred()));
}

void handleRecv(boost::system::error_code e, int bytes)
{
if (e.value() || !bytes)
{
handle_error();
return;
}
//do something with data read
do_something(m_recvBuffer);

doRead(); //read another packet
}

protected:
boost::array<char, 1024> m_recvBuffer;
boost::asio::ip::udp::endpoint m_from;
};

程序似乎会读取一个数据包,处理它,然后准备读取另一个数据包。简单的。但是如果我设置一个线程池呢?下一次调用 doRead() 应该在处理读取数据之前还是之后?似乎如果它放在 do_something() 之前,程序可以立即开始读取另一个数据包,如果它放在之后,线程就会被捆绑起来做任何事情 do_something() 可以,这可能需要一段时间。如果我将 doRead() 放在处理之前,这是否意味着 m_readBuffer 中的数据可能会在我处理它时发生变化?

此外,如果我正在使用 async_send_to(),我是否应该将要发送的数据复制到临时缓冲区中,因为实际发送可能要等到数据超出范围后才会发生?即

void send()
{
char data[] = {1, 2, 3, 4, 5};
m_sock->async_send_to(boost::buffer(&data[0], 5), someEndpoint, someHandler);
} //"data" gets deallocated, but the write might not have happened yet!

此外,当套接字关闭时,将调用 handleRecv 并显示错误,表明它已被中断。如果我这样做

Socket* mySocket = new Socket()...
...
mySocket->close();
delete mySocket;

它会导致错误吗,因为 mySocket 有可能在 handleRecv() 被调用/完成之前被删除?

最佳答案

这里有很多问题,我将尝试一次解决一个问题。

But what if I set up a thread pool?

在 Boost.Asio 中使用线程池的传统方法是调用 io_service::run() from multiple threads .请注意,这不是一个放之四海而皆准的答案,可能存在可扩展性或性能问题,但这种方法是迄今为止最容易实现的方法。类似的还有很多questions在 Stackoverflow 上了解更多信息。

Should the next call to doRead be before or after handling the read data? It seems that if it is put before do_something(), the program can immediately begin reading another packet, and if it is put after, the thread is tied up doing whatever do_something does, which could possibly take a while.

这实际上取决于 do_something() 需要对 m_recvBuffer 做什么。如果您希望使用 io_service::post()doRead() 并行调用 do_something(),您可能需要复制一份的 m_recvBuffer

If I put the doRead() before the handling, does that mean the data in m_readBuffer might change while I'm handling it?

正如我之前提到的,是的,这可能而且将会发生。

Also, if I'm using async_send_to(), should I copy the data to be sent into a temporary buffer, because the actual send might not happen until after the data has fallen out of scope?

作为documentation describes ,由调用者(您)确保缓冲区在异步操作期间保持在范围内。正如您所怀疑的那样,您当前的示例调用了未定义的行为,因为 data[] 将超出范围。

Additionally, when the socket is closed, the handleRecv() will be called with an error indicating it was interrupted.

如果你想继续使用套接字,使用cancel()interrupt outstanding异步操作。否则,close() 将起作用。在这两种情况下传递给未完成的异步操作的错误是 boost::asio::error::operation_aborted

关于c++ - boost::asio 异步操作和资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7295360/

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