2013-06-21 64 views
1

我想在共享內存中保留大量的(經常重複的)字符串,所以我使用了Boost的輕量級和進程間basic_string功能。爲了確保字符串實際存儲在共享內存中,我需要在flyweight使用的hashed_factory中提供一個自定義分配器。使用Boost輕量級共享內存

但是,當我將自定義分配器指定爲hashed_factory時,無法編譯(g ++ 4.2.1)...可能是因爲它需要額外的參數來指定段管理器。什麼是語法來得到這個工作,或者有更好的方法來做到這一點?

#include <boost/interprocess/managed_mapped_file.hpp> 
#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/interprocess/allocators/allocator.hpp> 
#include <boost/interprocess/containers/string.hpp> 
#include <boost/flyweight.hpp> 
#include <boost/flyweight/no_tracking.hpp> 
#include <boost/flyweight/hashed_factory.hpp> 

using namespace boost::flyweights; 
using namespace boost::container; 
using namespace boost::interprocess; 


typedef boost::interprocess::allocator<boost::mpl::_1, boost::interprocess::managed_mapped_file::segment_manager> ShmFactoryEntryAllocator; 

typedef boost::interprocess::allocator<char, boost::interprocess::managed_mapped_file::segment_manager> ShmAllocatorChar; 

typedef boost::interprocess::basic_string<char, std::char_traits<char>, ShmAllocatorChar> ShmString; 

// TODO: using ShmFactoryEntryAllocator does not work 
typedef boost::flyweights::hashed_factory<boost::hash<ShmString>, std::equal_to<ShmString>, ShmFactoryEntryAllocator> ShmStringHashedFactory; 
//typedef boost::flyweights::hashed_factory<boost::hash<ShmString>, std::equal_to<ShmString>, std::allocator<boost::mpl::_1> > ShmStringHashedFactory; 

// TODO: need to be able to use a hashed_factory with our custom allocator. 
typedef boost::flyweights::flyweight<ShmString, ShmStringHashedFactory> ShmFlyweightString; 
//typedef boost::flyweights::flyweight<ShmString> ShmFlyweightString; 


int main(int argc, char** argv) 
{ 
    managed_mapped_file *segment = new managed_mapped_file(create_only, "memory.dat", 409600); 
    ShmFactoryEntryAllocator factoryEntryAllocator(segment->get_segment_manager()); 

    // create a normal string in shared-memory. 
    ShmString *ps1 = segment->construct<ShmString>("s1")("some shm normal string", factoryEntryAllocator); 

    // create a flyweight string in shared memory. 
    ShmFlyweightString *ps2 = segment->construct<ShmFlyweightString>(anonymous_instance)("some shm flyweight string", factoryEntryAllocator); 

    return 0; 
} 

的TODO註釋後的線是有問題的線路,加上註釋的版本是說工作,但沒有使用正確的分配器的人。

回答

0

看起來你是正確的問題是所需的構造函數參數。所述hashed_factory docs說:

內部散列容器在其hashed_factory_class基於 構造有散列類型缺省初始化的對象,強的鬆和 分配器。

我想知道是否可以通過使共享內存分配器的子類具有默認構造函數,將段管理器傳遞給基類構造函數來解決此問題。例如,如下所示:

class MyShmAllocator : public ShmFactoryEntryAllocator { 
public: 
    static boost::interprocess::managed_mapped_file::segment_manager *segmentManager; 

    MyShmAllocator() 
    : ShmFactoryEntryAllocator(*segmentManager) { 
    } 
}; 

在調用構造函數之前,您需要先指定一個「current」MyShmAllocator :: segmentManager。這有點難看,但我認爲它應該起作用。

+0

我認爲這樣越來越接近了,但我仍然無法完成編譯。事實證明,MyShmAllocator構造函數實際上不應該取消引用指針。但是,在將ShmStringHashedFactory切換爲使用MyShmAllocator後,它仍然不太高興...... https://gist.github.com/bovine/5863647 – bovine

+0

事實證明,您的答案是正確的,但還有更多需要一個完整的解決方案,例如擁有知道如何存儲共享內存和鎖定策略的持有者類。我的同事在Boost郵件列表中提出了同樣的問題,並從JoaquínMLópezMuñoz那裏得到了非常全面的答案:http://permalink.gmane.org/gmane.comp.lib.boost.devel/242512 – bovine