If the address space is shared it is safe to use such an allocator for the complete structure
You're mixing "shared address space" and "address mapped at the same address". Because if there was no sharing of address space, there would also not be an issue storing raw pointers.
What is important is to use fancy pointers like boost::interprocess::offset_ptr<T>. The interprocess allocator uses offset_ptr<T>.
This is why you need to use container implementations that support fancy pointers.
You're very close. The canonical way to do what you sketch would look like this:
The boost version of the containers uses the pointer type由分配器指定。
这就是为什么 sallocator_traits 包括一个指针类型。
从理论上讲,STL实现(C ++ 11)应使用它,而不是假设原始指针。提升容器确保完成此操作。因此,增强分配器不仅返回Offset_ptr指针,而且还告知容器模板也应该使用它们。
Limitations When Constructing Objects In Mapped Regions
Offset pointers instead of raw pointers
References forbidden
Virtuality forbidden
Be careful with static class members
When two processes create a mapped region of the same mappable object,
two processes can communicate writing and reading that memory. A
process could construct a C++ object in that memory so that the second
process can use it. However, a mapped region shared by multiple
processes, can't hold any C++ object, because not every class is ready
to be a process-shared object, specially, if the mapped region is
mapped in different address in each process.
If you could get it to work with boost.interprocess it probably wouldn't be portable.
Boost does provide an alternative solution.
There are several pieces of magic which make this work:
offset pointers
telling a template type (e.g. container) to use offset pointers instead of raw pointers via the allocator
cascading this instruction to templated types automatically
Boost provides containers which use smart offset pointers (boost::interprocess::offset_ptr) which can be used in place of regular STL containers.
When the member type pointer is not a raw pointer type, it is commonly
referred to as a "fancy pointer". Such pointers were introduced to
support segmented memory architectures and are used today to access
objects allocated in address spaces that differ from the homogeneous
virtual address space that is accessed by raw pointers. An example of
a fancy pointer is the mapping address-independent pointer
boost::interprocess::offset_ptr, which makes it possible to allocate
node-based data structures such as std::set in shared memory and
memory mapped files mapped in different addresses in every process.
Fancy pointers can be used independently of the allocator that
provided them, through the class template std::pointer_traits (since
C++11). The function std::to_address can be used to obtain a raw
pointer from a fancy pointer. (since C++20)
Use of fancy pointers and customized size/different type in the
standard libary are conditionally supported. Implementations may
require that member type pointer, const_pointer, size_type, and
difference_type are value_type*, const value_type*, std::size_t, and
std::ptrdiff_t, respectively.
The boost version of the containers uses the pointer type specified by the allocator.
This is why allocator_traits includes a pointer type.
In theory an STL implementation (post C++11) should use it instead of assuming a raw pointer. Boosts containers ensure that this is done. So the boost allocator not only returns offset_ptr pointers but informs the container template that it should use them as well.
发布评论
评论(2)
您要混合的“共享地址空间”和“地址映射在同一地址”的完整结构。因为如果没有地址空间共享,也不会出现存储原始指针的问题。
重要的是使用
boost :: intercess :: offset_ptr&lt&lt; t&gt;
之类的精美指针。解释分配器使用offset_ptr&lt; t&gt;
。这就是为什么您需要使用支持花式指针的容器实现。
你很近。做您素描的规范方法:
>
输出第一次运行:
输出第二运行:
一如既往的奖金
,我不能对
scoped_allocator_adaptor
,这是切片半导体以来最好的东西:现在,wherewherewherewhere awhere
use_allocator
协议被用了,您会得到魔术分配的传播:>
输出相同
You're mixing "shared address space" and "address mapped at the same address". Because if there was no sharing of address space, there would also not be an issue storing raw pointers.
What is important is to use fancy pointers like
boost::interprocess::offset_ptr<T>
. The interprocess allocator usesoffset_ptr<T>
.This is why you need to use container implementations that support fancy pointers.
You're very close. The canonical way to do what you sketch would look like this:
Live On Coliru
Output first run:
Output second run:
BONUS
As always, I cannot be remiss about
scoped_allocator_adaptor
, the best thing since sliced semiconductors:Now, anywhere
uses_allocator
protocol is used, you get magic allocator propagation:Live On Coliru
With identical output
根据文档的答案是 no 。
在每个过程中都
Boost确实提供了替代解决方案。
有几块魔术可以使这项工作:
提升,可自动提供使用智能偏移指针的容器(<
https://stackoverflow.com/a/a/7159729/1569204 有一个清晰的解释(不是特定的):
这很聪明。我不确定为什么这尚未将其纳入ISO标准(也许它已经是无知的)。
请参阅 https://en.cppreference.com/w/nemed_req/nemed_req/allemed_req/allagreq/allalocator. #Fancy_Pointers
这里有一个很好的解释:
The boost version of the containers uses the pointer type由分配器指定。
这就是为什么 sallocator_traits 包括一个指针类型。
从理论上讲,STL实现(C ++ 11)应使用它,而不是假设原始指针。提升容器确保完成此操作。因此,增强分配器不仅返回Offset_ptr指针,而且还告知容器模板也应该使用它们。
另一个魔术是获取模板使用结构包含它的分配器的标准方法。
参见什么是”在C ++中使用分配器“和“范围分配器”构建
至少C ++ 11以来,这种魔术一直存在于C ++中。
The answer according to the documentation is no.
If you could get it to work with boost.interprocess it probably wouldn't be portable.
Boost does provide an alternative solution.
There are several pieces of magic which make this work:
Boost provides containers which use smart offset pointers (boost::interprocess::offset_ptr) which can be used in place of regular STL containers.
https://stackoverflow.com/a/7159729/1569204 has a concise explanation of how this type of pointer can be implemented (not boost specific):
This is very clever. I'm not sure why this has not yet made it into the ISO standard (perhaps it has and I am just ignorant).
See https://en.cppreference.com/w/cpp/named_req/Allocator#Fancy_pointers
There is a good explanation here:
The boost version of the containers uses the pointer type specified by the allocator.
This is why allocator_traits includes a pointer type.
In theory an STL implementation (post C++11) should use it instead of assuming a raw pointer. Boosts containers ensure that this is done. So the boost allocator not only returns offset_ptr pointers but informs the container template that it should use them as well.
The other bit of magic is a standard way of getting a template to use the allocator of the structure containing it.
See What is "uses allocator" and "scoped allocator" construction in c++
This bit of magic has been in C++ since at least C++11.