我试图更好地理解 async asio 的工作原理。
我有以下代码,我在套接字上调用 async_read 来读取接下来的 10 个字节的数据。
struct SocketReader {
void do_read_body()
{
asio::async_read(socket_,
asio::buffer(msg_, 10),
[this](asio::error_code ec, std::size_t length)
{
if (!ec)
{
//messages_to_work_on.emplace_back(msg_); // <-- I'm trying to send this msg_ instance to another io_context
do_read_body(); // call again
}
else
{
socket_.close();
}
});
}
std::vector<uint8_t> msg_;
asio::tcp::socket _socket;
}
这些读取是在他自己的 std::thread 中运行的 io_context 内完成的,我在队列中收集从套接字读取的所有消息。到目前为止,一切都很好。
我还有另一个“worker”类,它只是根据队列中可用的内容执行一些工作:
struct Worker
{
asio::io_context& io_context_;
std::deque< std::vector<uint8_t> > queue;
Worker(asio::io_context& io_context)
: io_context_(io_context) {
asio::post(io_context_, [this]() {doWork();});
}
void doWork() {
if (!queue.empty())
{
// do some work with front()
queue.pop_front();
}
asio::post(io_context_, [this]() {doWork();});
}
};
那一个也在他自己的 io_context 中执行,在他自己的线程中运行。所以socket线程和工作线程之间存在并发。
将从套接字接收到的数据发送到工作人员类的正确方法是什么?
我想我应该能够从套接字完成处理程序调用,例如:
asio::post(worker_io_context, [this]() {worker.queue.push_back(msg_)});
这样,我至少可以确定工作队列不会同时使用。
但我不确定是否允许我从一个 io_context 发布到另一个,也不确定我是否不会以这种方式创建另一个竞争条件。
我也不太明白消息的内存应该位于哪里,尤其是从一个 io_context 到另一个 io_context 的传输“之间”。是否需要按值传递消息(因为可以在执行后处理程序之前修改 this.msg_ )?
Thanks!