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