@john-lee
2021-01-01T17:04:44.000000Z
字数 1944
阅读 1212
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)