Home > OS >  Create boost::spsc queue in boost managed shared memory with a runtime size
Create boost::spsc queue in boost managed shared memory with a runtime size

Time:09-27

Shared-memory IPC synchronization (lock-free)

My use case aligns very closely with what has been described in the above question. But I wanted to go a step further in creating the spsc queue dynamically with a user defined runtime size. I tried implementing it with the following code:

void create_shared_spsc_queue(size_t sz)
{
    using char_alloc = boost::interprocess::allocator<char, boost::interprocess::managed_shared_memory::segment_manager>;
    using shared_string = boost::interprocess::basic_string<char, std::char_traits<char>, char_alloc>;
    using string_alloc = boost::interprocess::allocator<shared_string, boost::interprocess::managed_shared_memory::segment_manager>;

    using ring_buffer_dynamic = boost::lockfree::spsc_queue<shared_string, boost::lockfree::allocator<string_alloc> >;

    ring_buffer_dynamic *queue_dynamic_;
    boost::interprocess::managed_shared_memory segment_(boost::interprocess::open_only, "MySharedMemroy");
    string_alloc string_alloc_(segment_.get_segment_manager());


    queue_dynamic_ = segment_.construct<ring_buffer_dynamic>(rbuff_name)(string_alloc_, sz);
}

But this throws compilation error:

/usr/include/boost/interprocess/detail/named_proxy.hpp:85:7: error: no matching function for call to ‘boost::lockfree::spsc_queue<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, 
boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> > >, 
boost::lockfree::allocator<boost::interprocess::allocator<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0>, 0>, 
boost::interprocess::iset_index> > >, boost::interprocess::segment_manager<char, 
boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void, long int, long unsigned int, 0>, 0>, boost::interprocess::iset_index> > > >::spsc_queue(boost::interprocess::allocator<boost::container::basic_string<char, std::char_traits<char>, boost::interprocess::allocator<char, 
boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> > >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>, boost::interprocess::iset_index> >&, int)’
   85 |    {  ::new((void*)mem, boost_container_new_t())T(boost::forward<Args>(get<IdxPack>(args_))...); }

I can understand its related to issue with allocators, but I can't seem to resolve it, with my limited understanding of allocators. How can I implement this?

CodePudding user response:

For posterity: I figured, I was calling the ctor of spsc_queue in wrong order of arguments. The following works:

    queue_dynamic_ = segment_.construct<ring_buffer_dynamic>(rbuff_name)(sz, string_alloc_);

Source: https://www.boost.org/doc/libs/1_80_0/doc/html/boost/lockfree/spsc_queue.html

  • Related