2013-02-15 12 views
8

boost::lockfree::queue<<T, fixed_sized<false>, ..> を共有メモリに配置する際に問題があります。私はキューに65535件の以上のメッセージを挿入できるようにする必要があり、かつfixed_sizedキューが65535
に限定されている次のコードは正常に動作します(ただしcapacity<...>オプションがfixed_sized<true>を意味する)ので、私はそれを必要とする:共有メモリ内のboost :: lockfree :: queueの問題(boost 1.53、gcc 4.7.2/clang 3.0-6ubuntu3)

typedef boost::interprocess::allocator< 
    MessageT, 
    boost::interprocess::managed_shared_memory::segment_manager> 
     ShmemAllocator; 
typedef boost::lockfree::queue< 
    MessageT, 
    boost::lockfree::capacity<65535>, 
    boost::lockfree::allocator<ShmemAllocator> > 
     Queue; 
m_segment = new boost::interprocess::managed_shared_memory(
    boost::interprocess::create_only, segmentName, size); 
Queue* m_queue = m_segment->construct<Queue>(
    queueName)(
    m_segment->get_segment_manager()); 
... 
m_queue->bounded_push(message); 

コードは、次のことはあまりにも正常に動作する(それは共有メモリを使用しません):

boost::lockfree::queue<MessageT> q; 
.... 
q.bounded_push(message); 

しかし、私はそれを組み合わせるしようとすると:

typedef boost::interprocess::allocator< 
    MessageT, 
    boost::interprocess::managed_shared_memory::segment_manager> 
     ShmemAllocator; 
typedef boost::lockfree::queue< 
    MessageT, 
    boost::lockfree::allocator<ShmemAllocator> > 
     Queue; 
m_segment = new boost::interprocess::managed_shared_memory(
    boost::interprocess::create_only, segmentName, size); 
Queue* m_queue = m_segment->construct<Queue>(
    queueName)(
    m_segment->get_segment_manager()); 
... 
m_queue->bounded_push(message); 

それは以下のログを使用してコンパイルに失敗:

In file included from src/model/Queue.h:16: 

In file included from /home/uppi/lib/include/boost/lockfree/queue.hpp:24: 

/home/uppi/lib/include/boost/lockfree/detail/freelist.hpp:171:28: error: no viable conversion from 'pointer' (aka 'offset_ptr<boost::lockfree::queue<PacketMessage, 
     boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, 
     boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::node, long, unsigned long, 0UL>') to 
     'boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, 
     boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, 
     boost::parameter::void_>::node *' 
        return Alloc::allocate(1); 
          ~~~~~~~~~~~~~~~~~ 

/home/uppi/lib/include/boost/lockfree/detail/freelist.hpp:157:20: note: in instantiation of function template specialization 'boost::lockfree::detail::freelist_stack<boost::lockfree::queue<PacketMessage, 
     boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, 
     boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::node, 
     boost::interprocess::allocator<boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, 
     boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, 
     boost::parameter::void_>::node, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned 
     long, 0>, 0>, iset_index> > >::allocate_impl<true>' requested here 
      return allocate_impl<Bounded>(); 


/home/uppi/lib/include/boost/lockfree/detail/freelist.hpp:89:20: note: in instantiation of function template specialization 'boost::lockfree::detail::freelist_stack<boost::lockfree::queue<PacketMessage, 
     boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, 
     boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::node, 
     boost::interprocess::allocator<boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, 
     boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, 
     boost::parameter::void_>::node, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned 
     long, 0>, 0>, iset_index> > >::allocate<true, true>' requested here 
     T * node = allocate<ThreadSafe, Bounded>(); 


/home/uppi/lib/include/boost/lockfree/queue.hpp:281:34: note: in instantiation of function template specialization 'boost::lockfree::detail::freelist_stack<boost::lockfree::queue<PacketMessage, 
     boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, 
     boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::node, 
     boost::interprocess::allocator<boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, 
     boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, 
     boost::parameter::void_>::node, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned 
     long, 0>, 0>, iset_index> > >::construct<true, true, PacketMessage, boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, 
     boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, 
     boost::parameter::void_, boost::parameter::void_>::node *>' requested here 
     node * n = pool.template construct<true, Bounded>(t, pool.null_handle()); 


/home/uppi/lib/include/boost/lockfree/queue.hpp:270:16: note: in instantiation of function template specialization 'boost::lockfree::queue<PacketMessage, 
     boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, 
     boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, boost::parameter::void_, boost::parameter::void_>::do_push<true>' requested here 
     return do_push<true>(t); 


src/model/Queue.inl:4:18: note: in instantiation of member function 'boost::lockfree::queue<PacketMessage, boost::lockfree::allocator<boost::interprocess::allocator<PacketMessage, 
     boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long, unsigned long, 0>, 0>, iset_index> > >, 
     boost::parameter::void_, boost::parameter::void_>::bounded_push' requested here 
     return m_queue->bounded_push(message);       

/home/uppi/lib/include/boost/interprocess/offset_ptr.hpp:450:4: note: candidate function 
    operator unspecified_bool_type() const 

は、私は、共有メモリにboost::lockfree::queueまたはboost::lockfree::stackを使用して

+0

lockfreeの著者、Tim Blechmannにこれについて聞かれましたか?彼は通常かなり役に立つ。 – eile

+0

ありがとう、私は彼に電子メールを送ったばかりです – uppi

答えて

14

を欠けているものを私に教えて互換性のために、65535個の要素に制限されてください。シングルプロデューサ、シングルコンシューマのユースケースがある場合は、boost::lockfree::spsc_queueを使用します。しかし、これも動的なサイズではありません。

この制限は32ビット互換です。 64ビットプラットフォームの場合、16ビットインデックスの代わりに32ビットを使用するようにboost.lockfreeコードを適合させることができます。物事を正しく実装するためには、ほんのわずかな変更が必要になります。

+0

ありがとうございました – uppi

+0

@timblechmannしかし、プラットフォームx86_64がすでに10年ある場合、なぜboost :: lockfree :: queueの64ビット実装を実装していないのですか? – Alex

+0

@Alexは手を汚して、データ構造を設定するポリシーを追加するパッチを提供します;) – timblechmann

関連する問題