在Boost asio中股线文档 https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/overview/core/strands.html它说:
链可以是隐式的也可以是显式的,如以下替代方法所示:
- ...
- 如果存在与连接关联的单个异步操作链(例如,在像 HTTP 这样的半双工协议实现中),则处理程序不可能并发执行。这是一条隐含的链。
- ...
然而,在助推兽的多线程异步 http 服务器的示例 https://github.com/boostorg/beast/blob/master/example/http/server/async/http_server_async.cpp the boost::asio::ip::tcp::acceptor
以及每个boost::asio::ip::tcp::socket
得到自己的股明确地(见行373 https://github.com/boostorg/beast/blob/master/example/http/server/async/http_server_async.cpp#L373 and 425 https://github.com/boostorg/beast/blob/master/example/http/server/async/http_server_async.cpp#L425)。据我所知,这应该是没有必要的,因为所有这些对象只会在顺序注册/运行中被访问CompletionHandler
s. 准确地说,这些对象之一的新异步操作仅在一个对象的末尾注册。CompletionHandler
注册在同一个对象上,使得任何对象都可以在单链异步操作.²
因此,我假设 - 尽管有多个线程同时运行 - 在此示例和示例中可以一起省略链io_context
可用于直接调度任何异步操作。那是对的吗?如果不是,我缺少哪些同步问题?我是否误解了上述文档中的陈述?
1:当然,两个套接字或一个套接字和接受器可以同时使用,但由于使用multiple stand
示例中也没有阻止这种情况。
²:不可否认,CompletionHandler
在当前结束时注册CompletionHandler
可能在另一个线程上启动before当前处理程序实际上完成了,i。 e.returns。但我认为这不会带来同步问题的情况。如果我错了,请纠正我。
如果异步操作链创建逻辑链,那么通常您不需要显式链。
此外,如果执行上下文仅从单个线程运行/轮询,则所有异步操作都将在该隐式链上有效。
这些示例有多个目的。
-
一方面。它们显然保持简单。当然,会有最少数量的线程或简单的操作链。
-
然而,这会导致例子过于简单化,与现实生活联系太少。
-
因此,即使不是绝对地根据需要,样本通常表现出良好的实践或先进的模式。有时(通常是输入法)甚至会明确注释这一点。例如。在你非常链接的例子中L277 https://github.com/boostorg/beast/blob/master/example/http/server/async/http_server_async.cpp#L277:
// 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::do_read,
shared_from_this()));
励志例子
这使得人们能够解决下一个重要的任务。例如,假设您想添加stop()
to the listener
链接示例中的类。如果没有一根线,就没有办法安全地做到这一点。您需要“注入”一个电话acceptor.cancel()
inside逻辑“链”,异步操作链包含async_accept
。但你不能,因为async_accept
是“逻辑上阻塞”该链。所以你实际上确实需要发布到一个显式的链:
void stop() {
post(acceptor_.get_executor(), [this] { acceptor_.cancel(); });
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)