使用共享内存的Boost flyweight

使用共享内存的Boost flyweight,boost,stdstring,boost-interprocess,boost-flyweight,Boost,Stdstring,Boost Interprocess,Boost Flyweight,我希望在共享内存中保留大量(经常重复的)字符串,因此我使用Boost的flyweight和进程间基本_字符串功能。为了确保字符串实际存储在共享内存中,我需要在flyweight使用的hash_工厂中提供一个自定义分配器 然而,当我将我的自定义分配器指定给哈希_工厂时,这无法编译(g++4.2.1)。。。可能是因为它需要一个额外的参数来指定段管理器。什么样的语法可以让它工作,或者有更好的方法吗 #include <boost/interprocess/managed_mapped_file.

我希望在共享内存中保留大量(经常重复的)字符串,因此我使用Boost的flyweight和进程间基本_字符串功能。为了确保字符串实际存储在共享内存中,我需要在flyweight使用的hash_工厂中提供一个自定义分配器

然而,当我将我的自定义分配器指定给哈希_工厂时,这无法编译(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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间boost::flyweights;
使用名称空间boost::container;
使用名称空间boost::interprocess;
typedef boost::进程间::分配器ShmFactoryEntryAllocator;
typedef boost::进程间::分配器ShmAllocatorChar;
typedef boost::进程间::基本字符串ShmString;
//TODO:使用ShmFactoryEntryAllocator不起作用
typedef boost::flyweights::hashed_工厂shmstringhashed工厂;
//typedef boost::flyweights::hashed_工厂shmstringhashed工厂;
//TODO:需要能够在自定义分配器中使用哈希_工厂。
typedef boost::flyweights::flyweight ShmFlyweightString;
//typedef boost::flyweights::flyweight ShmFlyweightString;
int main(int argc,字符**argv)
{
托管映射文件*段=新的托管映射文件(仅创建“memory.dat”,409600);
ShmFactoryEntryAllocator factoryEntryAllocator(段->获取段\管理器());
//在共享内存中创建普通字符串。
ShmString*ps1=段->构造(“s1”)(“一些shm普通字符串”,factoryEntryAllocator);
//在共享内存中创建flyweight字符串。
ShmFlyweightString*ps2=段->构造(匿名_实例)(“某个shm flyweightstring”,factoryEntryAllocator);
返回0;
}

TODO注释后的行是有问题的行,注释的版本是有效的,但没有使用正确的分配器。

看来您认为问题是所需的构造函数参数是正确的。他们说:

哈希工厂类所基于的内部哈希容器 使用哈希、Pred和 分配器

我想知道您是否可以通过创建共享内存分配器的一个子类来解决这个问题,该子类有一个默认构造函数,将段管理器传递给基类构造函数。例如,类似这样的内容:

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

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

在调用构造函数之前,需要分配一个“当前”myshmlocator::segmentManager。它有点难看,但我认为它应该可以工作。

我认为这一点越来越接近了,但我仍然无法将其编译。事实证明,myshmlocator构造函数实际上不应该取消对指针的引用。但是,在将ShmStringHashedFactory切换到使用myshmlocator之后,它仍然不是很高兴。。。事实证明,您的答案是正确的,但是对于一个完整的解决方案来说,还需要更多的东西,例如拥有一个知道如何存储在共享内存中的holder类和锁定策略。我的同事在Boost邮件列表上问了同样的问题,并从Joaqín M López Muñoz那里得到了非常全面的回答: