2013-02-15 12 views
8

Mam problem z umieszczeniem boost::lockfree::queue<<T, fixed_sized<false>, ..> we wspólnej pamięci. Muszę, bo muszę być w stanie włożyć więcej niż 65535 wiadomości w kolejce, a fixed_sized kolejka jest ograniczona z 65535.
Poniższy kod działa poprawnie (ale capacity<...> opcja zakłada fixed_sized<true>):Problemy z boost :: lockfree :: kolejka we wspólnej pamięci (doładowanie 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); 

następujący kod działa poprawnie też (ale nie korzysta z pamięci współdzielonej):

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

ale gdy próbuję połączyć go:

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); 

nie powiedzie się skompilować z poniższej dzienniku:

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 

Proszę mi powiedzieć, co mi brakuje

+0

Czy zapytałeś o to Tima Blechmanna, autora Lockfree? Zwykle jest bardzo pomocny. – eile

+0

Dziękuję, właśnie wysłałem mu e-mail – uppi

Odpowiedz

14

użyciu boost::lockfree::queue lub boost::lockfree::stack w pamięci współdzielonej jest ograniczona do 65535 elementów, ze względu na kompatybilność. jeśli masz jednego producenta, jednego konsumenta przypadek użycia, możesz chcieć użyć boost::lockfree::spsc_queue. nie ma to jednak również rozmiaru dynamicznego.

powodem tego ograniczenia jest kompatybilność z 32-bitową. na platformach 64-bitowych można dostosować kod boost.lockfree do 32-bitowych zamiast 16-bitowych indeksów. ale wymagałoby to pewnych nietrywialnych zmian w celu prawidłowego wdrożenia rzeczy.

+0

Dzięki za wyjaśnienie – uppi

+0

@timblechmann Ale jeśli platforma x86_64 istnieje już od 10 lat, to dlaczego nie wdrożyła 64-bitowej implementacji kolejki boost :: lockfree :: queue? – Alex

+0

@Alex po prostu zabrudzić sobie ręce i dostarczyć łatkę, która dodaje zasadę do konfiguracji struktury danych;) – timblechmann

Powiązane problemy