Trong boost::interprocess
tài liệu hướng dẫn người ta nói như yêu cầu đối với các container được lưu trữ trong bộ nhớ chia sẻ:Liệu std :: vector có đáp ứng các yêu cầu vùng chứa cho các trình phân bổ Boost.Interprocess không?
- STL container có thể không thừa nhận rằng bộ nhớ được phân bổ với một cấp có thể được deallocated với allocators khác cùng loại. Tất cả các đối tượng cấp phát phải so sánh chỉ bằng nhau nếu bộ nhớ được cấp phát với một đối tượng có thể được deallocated với một đối tượng khác, và điều này chỉ có thể được kiểm tra với
operator==()
khi chạy. - Con trỏ bên trong của bộ chứa phải thuộc loại
allocator::pointer
và vùng chứa có thể không giả địnhallocator::pointer
là con trỏ thô. - Tất cả các đối tượng phải được xây dựng phá hủy thông qua các chức năng
allocator::construct
vàallocator::destroy
.
Tôi đang sử dụng gcc 4.7.1 với -std = C++ 11 (và tăng 1.53). Có an toàn không khi sử dụng loại ShmVector
được xác định dưới đây?
typedef boost::interprocess::allocator<int,
boost::interprocess::managed_shared_memory::segment_manager> ShmemAllocator;
typedef std::vector<int, ShmemAllocator> ShmVector;
Tôi đã thử một trình giả trong đó sử dụng loại này, và có vẻ nó đang làm việc, nhưng tôi vẫn không chắc chắn rằng các vector trong gcc4.7.1 không đáp ứng tất cả các yêu cầu. Tôi đặc biệt không chắc chắn về yêu cầu đầu tiên.
#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;
}
}
Theo tiêu chuẩn, sẽ ổn thôi. – Xeo
@Xeo Tôi không chắc lắm. Tiêu chuẩn nói rằng việc triển khai STL là miễn phí để giả sử một người cấp phát cùng loại có thể giải quyết bộ nhớ; hầu hết các triển khai không dựa vào điều này, nhưng bạn nên kiểm tra tài liệu của thư viện 'std'. Tuy nhiên, với sự phổ biến của 'g ++' và' libstdC++ ', tôi sẽ ngạc nhiên nếu Boost không cảnh báo bạn về sự không tương thích một cách rõ ràng. –
@Xeo Tôi đã tìm thấy trong tiêu chuẩn, dấu đầu dòng 3 đó là đúng đối với tất cả std :: containers: 23.2.1.3. Nhưng không thể tìm thấy bất cứ điều gì cho bullet 1 và 2. –