Why is `net::dispatch` needed when the I/O object already has an executor?(当I/O对象已经有Executor时,为什么需要`net::Dispatch`?)
问题描述
我正在从本例中学习Boost.Beast&;Boost.Asiolibs/beast/example/http/server/async-ssl/http_server_async_ssl.cpp - 1.77.0。
据我所知,发生在I/O对象上的所有I/O操作都发生在该对象的I/O执行上下文中。异步操作将与I/O上下文的run位于同一线程中,因为它们都由I/O上下文的run(间接)调用。
在本例中(请参见上面的链接),当连接建立时,接受者为新连接分配一条专用链:
do_accept()
{
// The new connection gets its own strand
acceptor_.async_accept(
net::make_strand(ioc_),
beast::bind_front_handler(
&listener::on_accept,
shared_from_this()));
}
这是否意味着在新连接上发生的所有I/O操作都发生在链上?如果是,为什么该示例在要调用async_read时使用net::dispatch再次指定链?
// Start the asynchronous operation
void
run()
{
// We need to be executing within a strand to perform async operations
// on the I/O objects in this session. Although not strictly necessary
// for single-threaded contexts, this example code is written to be
// thread-safe by default.
net::dispatch(
stream_.get_executor(),
beast::bind_front_handler(
&session::on_run,
shared_from_this()));
}
如果我们直接调用async_read而不经过net::dispatch,有什么区别?谢谢。:)
推荐答案
这是否意味着在新连接上发生的所有I/O操作都发生在链上?
这意味着接受的套接字将获得引用该链的Executor的副本。这确实意味着从该服务对象启动的所有异步操作在默认情况下(!)将在该链上调用它们的完成处理程序。但是,这不适用于任何其他操作,如启动函数(例如s.async_read_some)本身。
因此,为了确保所有操作都发生在链上,您必须确保所有启动都发生在同一链上。在许多情况下,这将是自动的,因为许多启动发生在前一个操作的完成中-因此已经在链上-但不是第一个操作,如您所见。
(可以说,在新链的开始处,因此当刚刚创建IO对象并且该链是该IO对象的私有时,可以从任何线程安全地进行第一次发起,逻辑上成为链中的一部分。你可以把它看作是链本身的分叉点(诞生)。这是因为没有正在运行的操作,也没有其他线程可能持有对它的引用。)这篇关于当I/O对象已经有Executor时,为什么需要`net::Dispatch`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:当I/O对象已经有Executor时,为什么需要`net::Dispatch`?
基础教程推荐
- 提升 ASIO 流缓冲 2021-01-01
- 将不可复制的闭包对象传递给 std::function 参数 2021-01-01
- 如何部分禁用 cmake C/C++ 自定义编译器检查 2021-01-01
- C++:获取传递给函数的多维数组的行大小 2021-01-01
- c++ STL设置差异 2022-01-01
- 如何更改 SysDateTimePick32 或 CDateTimeCtrl 的背景颜色? 2022-01-01
- 如何在 C++ 中正确使用命名空间? 2022-01-01
- 为什么我们不能使用“虚拟继承"?在 COM 中? 2022-01-01
- 随机插入/删除的综合向量与链表基准 2022-01-01
- 与 CAS 的原子交换(使用 gcc 同步内置函数) 2022-01-01
