@john-lee
2021-01-03T02:42:36.000000Z
字数 1556
阅读 684
Boost.Asio
许多异步操作需要分配对象以存储与操作关联的状态。例如,Win32 实现需要OVERLAPPED
派生的对象传递给 Win32 API 函数。
此外,程序通常包含易于识别的异步操作链。半双工协议实现(例如 HTTP 服务器)将为每个客户机提供一个操作链(先接收,然后发送)。全双工协议实现将有两个并行执行的链。程序应该能够利用这些知识为链中的所有异步操作重用内存。
对于一个用户定义的Handler
对象的副本h
,如果实现需要分配与该处理程序关联的内存,它将使用get_associated_allocator
函数获得一个分配器。例如:
boost::asio::associated_allocator_t<Handler> a = boost::asio::get_associated_allocator(h);
关联的分配器必须满足标准分配器要求。
默认情况下,处理程序使用标准分配器(按照::operator new()
和::operator delete()
实现)。可以通过指定嵌套类型allocator_type
和成员函数get_allocator()
,为特定处理程序类型自定义分配器:
class my_handler
{
public:
// Custom implementation of Allocator type requirements.
typedef my_allocator allocator_type;
// Return a custom allocator implementation.
allocator_type get_allocator() const noexcept
{
return my_allocator();
}
void operator()() { ... }
};
在更复杂的情况下,associated_allocator
模板可能直接偏特化:
namespace boost { namespace asio {
template <typename Allocator>
struct associated_allocator<my_handler, Allocator>
{
// Custom implementation of Allocator type requirements.
typedef my_allocator type;
// Return a custom allocator implementation.
static type get(const my_handler&,
const Allocator& a = Allocator()) noexcept
{
return my_allocator();
}
};
} } // namespace boost::asio
这个实现保证了释放将在调用相关的处理程序之前发生,这意味着内存已经准备好被重新用于处理程序启动的任何新的异步操作。
自定义内存分配函数可以从调用库函数的任何用户创建的线程调用。该实现保证,对于库中包含的异步操作,该实现不会对该处理程序的内存分配函数进行并发调用。如果需要从不同线程调用分配函数,实现将插入适当的内存屏障,以确保正确的内存可见性。
associated_allocator,get_associated_allocator,自定义内存分配示例 (C++03),自定义内存分配示例 (C++11)。
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)