@john-lee
2021-01-01T17:04:44.000000Z
字数 1944
阅读 1087
Boost.Asio
Strand定义为事件处理程序的严格顺序调用(即没有并发调用)。使用Strand允许在多线程程序中执行代码,而无需显式锁定(例如,使用互斥)。
如以下替代方法所示,Strand可以是隐式或显式的:
io_context::run()
意味着所有事件处理程序都在隐式链中执行,因为io_context
保证仅从run()
内部调用处理程序。strand<>
或io_context::strand
的实例。所有事件处理程序函数对象都需要使用boost::asio::bind_executor()
绑定到strand或者通过strand对象以其他方式发布/调度。对于组合异步操作,如async_read()
或async_read_until()
,如果完成处理程序通过strand,则所有中间处理程序也应该经历相同的strand。这是确保调用方和组合操作之间共享的任何对象的线程安全访问(在async_read()
的情况下,它是套接字,调用方可以close()
)取消操作)。
为此,所有异步操作都使用get_associated_executor
函数获取处理程序的关联执行器。例如:
boost::asio::associated_executor_t<Handler> a = boost::asio::get_associated_executor(h);
关联的执行器必须满足执行器的要求。异步操作将使用它提交中间处理程序和最终处理程序以执行。
通过指定嵌套类型executor_type
和成员函数get_executor()
,可以针对特定处理程序类型自定义执行器:
class my_handler
{
public:
// Custom implementation of Executor type requirements.
typedef my_executor executor_type;
// Return a custom executor implementation.
executor_type get_executor() const noexcept
{
return my_executor();
}
void operator()() { ... }
};
在更复杂的情况下,associated_executor
模板可能直接偏特化:
struct my_handler
{
void operator()() { ... }
};
namespace boost { namespace asio {
template <class Executor>
struct associated_executor<my_handler, Executor>
{
// Custom implementation of Executor type requirements.
typedef my_executor type;
// Return a custom executor implementation.
static type get(const my_handler&,
const Executor& = Executor()) noexcept
{
return my_executor();
}
};
} } // namespace boost::asio
boost::asio::bind_executor()
函数是一个助手,用于将特定执行器对象(如strand)绑定到完成处理程序。这个绑定自动关联一个执行器,如上所示。例如,要将strand绑定到完成处理程序,我们只需编写:
my_socket.async_read_some(my_buffer,
boost::asio::bind_executor(my_strand,
[](error_code ec, size_t length)
{
// ...
}));
associated_executor, get_associated_executor, bind_executor, strand, io_context::stand, 教程定时器.5, HTTP服务器 3 示例。
Copyright © 2003-2020 Christopher M. Kohlhoff
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)