当 I/O 对象已经有一个执行器时,为什么还需要 net::dispatch?
Why is `net::dispatch` needed when the I/O object already has an executor?
我正在从这个例子中学习 Boost.Beast & Boost.Asio libs/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
调用(间接)。
在这个例子中(请见上文link),当连接建立时,接受者为新连接分配一个专用链:
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()));
}
不经过net::dispatch
直接调用async_read
有什么区别?谢谢。 :)
Does it imply that all I/O operations that happen on the new connections happen in the strand?
表示accepted socket得到了引用strand的executor的副本。这 确实 意味着从该服务对象启动的所有异步操作将 默认情况下 (!) 在该链上调用它们的完成处理程序。但是,这不适用于任何其他操作,例如启动函数(例如 s.async_read_some
)本身。
因此,要确保所有操作都发生在链上,您必须确保任何启动都发生在同一链上。在许多情况下,这将是自动的,因为许多启动发生在前一个操作的完成中 - 因此已经在链上 - 但不是第一个,如您所见。
(可以说,在一个新链的开始,所以当一个 IO 对象刚刚被创建并且该链是该 IO 对象私有的时,第一次启动可以安全地从任何线程,逻辑上成为 strand 的一部分。您可以将其视为 strand 本身的分叉点(“诞生”)。那是因为没有任何操作可以进行中,并且没有其他线程可能持有对它的引用。)
我正在从这个例子中学习 Boost.Beast & Boost.Asio libs/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
调用(间接)。
在这个例子中(请见上文link),当连接建立时,接受者为新连接分配一个专用链:
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()));
}
不经过net::dispatch
直接调用async_read
有什么区别?谢谢。 :)
Does it imply that all I/O operations that happen on the new connections happen in the strand?
表示accepted socket得到了引用strand的executor的副本。这 确实 意味着从该服务对象启动的所有异步操作将 默认情况下 (!) 在该链上调用它们的完成处理程序。但是,这不适用于任何其他操作,例如启动函数(例如 s.async_read_some
)本身。
因此,要确保所有操作都发生在链上,您必须确保任何启动都发生在同一链上。在许多情况下,这将是自动的,因为许多启动发生在前一个操作的完成中 - 因此已经在链上 - 但不是第一个,如您所见。
(可以说,在一个新链的开始,所以当一个 IO 对象刚刚被创建并且该链是该 IO 对象私有的时,第一次启动可以安全地从任何线程,逻辑上成为 strand 的一部分。您可以将其视为 strand 本身的分叉点(“诞生”)。那是因为没有任何操作可以进行中,并且没有其他线程可能持有对它的引用。)