I have a problem with placing boost::lockfree::queue<<T, fixed_sized<false>, ..>
in shared memory. I need it because I have to be able to insert more than 65535 messages into the queue, and fixed_sized queue is limited with 65535.
The following code works properly (but capacity<...>
option implies fixed_sized<true>
):
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);
The following code works properly too (but it doesn't use shared memory):
boost::lockfree::queue<MessageT> q;
....
q.bounded_push(message);
But when I try to combine it:
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);
it fails to compile with the following log:
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
Please tell me what I'm missing
using boost::lockfree::queue
or boost::lockfree::stack
in shared memory is limited to 65535 elements, for compatibility reasons. if you have a single-producer, single-consumer use-case, you might want to use the boost::lockfree::spsc_queue
. however this is also not dynamically-sized.
reason for this is limitation is 32bit compatibility. for 64bit platforms one might be able to adapt the boost.lockfree code to use 32bit instead of 16bit indices. but it would require some non-trivial changes to implement things correctly.
来源:https://stackoverflow.com/questions/14893246/trouble-with-boostlockfreequeue-in-shared-memory-boost-1-53-gcc-4-7-2-cl