2015-11-23 31 views
1

我知道boost interprocess containers,並且這些示例使用託管共享內存。但我想用一個簡單的boost::interprocess::shared_memory_object,裏面有一個對象,以及一個矢量或該對象內的任何其他容器。這似乎並不奏效。將矢量或任何其他容器存儲在boost進程shared_memory_object中?

試過這樣:

#include <stack> 
#include <boost/interprocess/containers/vector.hpp> 

namespace bip = boost::interprocess; 

class SharedMemoryMetadata 
{ 
public: 
    std::stack<unsigned short> newData; 
    int deleteme; 
    bip::vector<unsigned short> v; 
}; 

,並創建共享內存:

bip::shared_memory_object::remove(OUTPUT_METADATA_MEMORY_SEGMENT_NAME); 
sharedMemoryMetadataForOutput = new bip::shared_memory_object(bip::create_only, OUTPUT_METADATA_MEMORY_SEGMENT_NAME, bip::read_write);//use old shared memory if exists else create a new one 
sharedMemoryMetadataForOutput->truncate(sizeof(SharedMemoryMetadata)+ (3*sizeof(unsigned int)*MAX_NUMBER_OF_OBJECTS_EXPECTED_TO_BE_IN_SHARED_MEMORY));//set the size of the memory object 
sharedMemoryMetadataRegion = new bip::mapped_region(*sharedMemoryMetadataForOutput, bip::read_write);//map the whole shared memory in this process 
void* sharedMemorySegmentForMetadataStorage = sharedMemoryMetadataRegion->get_address();//get the region address 
sharedMemoryMetadataObject = new (sharedMemorySegmentForMetadataStorage) SharedMemoryMetadata();//create a shared memory buffer in memory 

,我嘗試訪問它:

bip::shared_memory_object* sharedMemoryMetadataForOutput; 
SharedMemoryMetadata* sharedMemoryMetadataObject; 
bip::mapped_region* sharedMemoryMetadataRegion; 

bip::shared_memory_object* sharedMemoryMetadataForOutput; 
SharedMemoryMetadata* sharedMemoryMetadataObject; 
bip::mapped_region* sharedMemoryMetadataRegion; 
sharedMemoryMetadataForOutput = new bip::shared_memory_object(bip::open_only, OUTPUT_METADATA_MEMORY_SEGMENT_NAME, bip::read_write);//create a shared memory object http://blog.wolfgang-vogl.com/?p=528 
sharedMemoryMetadataRegion = new bip::mapped_region(*sharedMemoryMetadataForOutput, bip::read_write);//Map the whole shared memory in this process   
void * sharedMemorySegmentForMetadataStorage = sharedMemoryMetadataRegion->get_address();//get the region address 
sharedMemoryMetadataObject = static_cast<SharedMemoryMetadata*>(sharedMemorySegmentForMetadataStorage);//Obtain the shared structure 

如預期,std::stack<unsigned short> newData;真可謂即使有東西寫入堆棧,也是空的。但是如果我給int deleteme賦值,我可以從另一個訪問共享內存的程序中讀取它。

push_backbip::vector<unsigned short> v;有效,但是當我嘗試從其他程序訪問它時,出現分段錯誤。有沒有一種方法可以在shared_memory_object中存儲和訪問矢量,或者只能使用託管共享內存?即使我使用託管共享內存,我如何將向量存儲在SharedMemoryMetadata類中,如上所示?

回答

1

我將以向量爲例來解釋。基本上,std::vector是這樣的:

template<typename T> 
struct vec { 
    std::size_t size; 
    T * data; 
}; 

當你把這個到任何共享內存,你分享本質上是一個大小和指針

當您添加元素的載體,它要求其分配器內存將它們存儲到。在你的例子中,這是默認分配器std::allocator,它又調用operator new

因此,矢量從非共享堆內存中獲取內存來存儲其元素。因此,指向此(非共享)內存的(共享)指針在另一個地址空間中將無效,從而導致未定義的行爲。

爲了解決這個問題,你要麼需要一個載體,其是意識到被共享(或設計爲),或者你自己寫的自己的分配器是從共享內存分配,並使用與STL類。

+0

謝謝。我已經意識到分配的概念。我希望得到的是一個解決方案或一個工作代碼。如果沒有簡單的解決方案,我會繼續並刪除我的問題。 – Nav

相關問題