std :: vector是否满足Boost.Interprocess分配器的容器需求? [英] Does std::vector satisfy the container requirements for Boost.Interprocess allocators?
问题描述
在 boost :: interprocess
文档中,它被认为是要存储在共享内存中的容器:
In boost::interprocess
documentation it is said as requirement for containers to be stored in shared memory:
- STL容器不能假定分配给分配器的内存可以被相同类型的其他分配器释放。只有当分配给一个对象的内存可以被解除分配给另一个对象时,所有分配器对象必须比较相等,并且这只能在运行时用
operator ==()
进行测试。 - 容器的内部指针应该是
allocator :: pointer
类型,容器不能假设allocator: c:> c: c: c:和
allocator :: destroy
函数。
- STL containers may not assume that memory allocated with an allocator can be deallocated with other allocators of the same type. All allocators objects must compare equal only if memory allocated with one object can be deallocated with the other one, and this can only tested with
operator==()
at run-time. - Containers' internal pointers should be of the type
allocator::pointer
and containers may not assumeallocator::pointer
is a raw pointer. - All objects must be constructed-destroyed via
allocator::construct
andallocator::destroy
functions.
我使用gcc 4.7.1与-std = c ++ 11(和boost 1.53)。 使用以下定义的 ShmVector
类型安全吗?
I am using gcc 4.7.1 with -std=c++11 (and boost 1.53). Is it safe to use the below defined ShmVector
type?
typedef boost::interprocess::allocator<int,
boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
typedef std::vector<int, ShmemAllocator> ShmVector;
我试过一个使用这种类型的虚拟进程,它看起来工作,但我仍然不确定gcc4.7.1中的向量是否满足所有要求。我特别不确定第一个要求。
I tried a dummy process which uses this type, and it looks it is working, but I am still not sure that the vector in gcc4.7.1 does satisfy all the requirements. I am especially not sure about the first requirement.
#include <iostream>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <vector>
#include <cstdlib> //std::system
typedef boost::interprocess::allocator<int,
boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
typedef std::vector<int, ShmemAllocator> ShmVector;
int main(int argc, char *argv[])
{
if(argc == 1){ //Parent process
struct shm_remove
{
shm_remove() { boost::interprocess::shared_memory_object::remove("MySharedMemory"); }
~shm_remove(){ boost::interprocess::shared_memory_object::remove("MySharedMemory"); }
} remover;
//Create a new segment with given name and size
boost::interprocess::managed_shared_memory segment(boost::interprocess::create_only,
"MySharedMemory", 65536);
//Initialize shared memory STL-compatible allocator
const ShmemAllocator allocator(segment.get_segment_manager());
ShmVector* v = segment.construct<ShmVector>("ShmVector")(allocator);
v->push_back(1); v->push_back(2); v->push_back(3);
//Launch child process
std::string s(argv[0]); s += " child ";
if(0 != std::system(s.c_str()))
return 1;
} else { // Child process
//Open the managed segment
boost::interprocess::managed_shared_memory segment(
boost::interprocess::open_only, "MySharedMemory");
//Find the vector using the c-string name
ShmVector *v = segment.find<ShmVector>("ShmVector").first;
for (const auto& i : *v) {
std::cout << i << " ";
}
std::cout << std::endl;
}
}
推荐答案
在C ++ 11中,分配器规则稍有改变,但我不认为它会影响你的问题。
In C++ 11 allocator rules have slightly changed, but I don't think it affects your question.
你可能想先知道什么标准说的。但你实际上想检查你的特定的STL实现是否符合标准,并且不包含错误。
You probably want to know first what standard says about it. But you'd actually want to check whether your specific STL implementation conforms to the standard and doesn't contain bugs.
对于第二部分,我强烈建议去
For the second part I'd strongly recommend going to sources of and just checking that, it's not that hard actually.
另外,你可以写你的测试,看看它是否能正常工作:
Also, you could write your tests to see if it's actually working properly:
- 创建自定义分配器:
- 使用一些自定义类型作为指针,const指针;
- 在
中构造()
,destruct()
计数调用次数;
- Create custom allocator:
- use some custom type as pointer, const pointer;
- In
construct()
,destruct()
count number of calls;
-
的数量调用等于
YourCustomType
的构造破坏数。 -
typeid(YourCustomAllocator :: pointer)== typeid(std :: vetor< YourCustomType,YourCustomAllocator< YourCustomType>> :: pointer)
- number of
construct()
destruct()
calls is equal to number of constructions destructions ofYourCustomType
. typeid(YourCustomAllocator::pointer) == typeid(std::vetor<YourCustomType, YourCustomAllocator<YourCustomType>>::pointer)
这样可以确保所有限制都适用。
That's how you can be sure that all restrictions apply.
至于问题的第一部分,这里有一个 old C ++ standard (not C ++ 11)。
As for the first part of the question, here's an old C++ standard (not C++ 11).
1 没有办法(正确实现)向量将使分配器无法运行。它将使用你提供的任何分配器,并将其用于一切。对于operator ==,它是在boost的分配器中实现的,因此它的boost的问题使operator ==按需要工作。虽然我无法在标准中找到确认信息
1 There's no way (properly implemented) vector will take an allocator out of nowhere. It'll use whatever allocator you provide, and will use it for everything. As for operator==, it is implemented in boost's allocator and thus it's boost's problem to make operator== work as they require. Although I wasn't able to find confirmation in the standard.
2 除非有错误,否则
std :: vector< T,YourAllocator> ::指针
应该是分配器的指针。 cppreference.com说,标准说,(查找模板类向量):2 Unless there's a bug,
std::vector<T, YourAllocator>::pointer
should be allocator's pointer. cppreference.com says that, and the standard says that, (look for "Template class vector"):typedef typename Allocator::pointer pointer; typedef typename Allocator::const_pointer const_pointer;
虽然相同的标准说这个分配器:
本国际标准中描述的容器的实现
允许假设它们的分配器模板参数满足
除了表6中的那些额外的要求。Although the same standard says this about allocators: Implementations of containers described in this International Standard are permitted to assume that their Allocator template parameter meets the following two additional requirements beyond those in Table 6.
- 给定分配器的所有实例
--All instances of a given allocator type are required to be inter- changeable and always compare equal to each other.
- typedef成员指针const_pointer,size_type和vary-
ence_type必须分别为T *,T const *,size_t和ptrdiff_t,
。>因此,实际上标准不允许使用任何指针类型,但我的猜测是实际的STL实现将工作。
So, actually standard doesn't allow using any pointer types, but my guess is that actual STL implementations will work.
3 只需检查
std :: vector< T> :: clear()
方法实现,看看是否调用了allocator :: destroy。检查std :: vector< T> :: resize()
方法的实现,看看是否使用了allocator :: construct。我不能在标准。3 Just check the
std::vector<T>::clear()
method implementation to see if allocator::destroy is called. Checkstd::vector<T>::resize()
method's implementation to see if allocator::construct is used. I was not able to find requirement of calling destroy and construct in the standard.这篇关于std :: vector是否满足Boost.Interprocess分配器的容器需求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!