Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

c++ - Trouble with boost::lockfree::queue in shared memory (boost 1.53, gcc 4.7.2 / clang 3.0-6ubuntu3)

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...