首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >boost check_sanity()互斥锁

boost check_sanity()互斥锁
EN

Stack Overflow用户
提问于 2022-06-12 22:23:37
回答 1查看 96关注 0票数 1

我有两个进程使用boost共享内存,运行在一个循环中。

在每次迭代中,流程在共享内存中执行某些操作之前调用check_sanity(),我有一个场景,其中一个进程因对齐问题而崩溃:

代码语言:javascript
复制
/usr/local/include/boost/interprocess/mem_algo/detail/mem_algo_common.hpp:106: static void boost::interprocess::ipcdetail::memory_algorithm_common<MemoryAlgorithm>::assert_alignment(boost::interprocess::ipcdetail::memory_algorithm_common<MemoryAlgorithm>::size_type) [with MemoryAlgorithm = boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family>; boost::interprocess::ipcdetail::memory_algorithm_common<MemoryAlgorithm>::size_type = long unsigned int]: Assertion `uint_ptr % Alignment == 0' failed.
./start.sh: line 20:  3034 Aborted                 (core dumped)

崩溃后,第二个进程卡在check_sanity()函数中,当第一个进程重新启动时,他也会停留在那里。

我看了一下boost源代码,我发现check_sanity()函数中有一个check_sanity(),那里有一个assert,所以我猜想,assert中的第一个进程崩溃而没有解锁scoped mutex

助推共享内存理智()源代码:

代码语言:javascript
复制
template<class MutexFamily, class VoidPointer, std::size_t MemAlignment>
bool rbtree_best_fit<MutexFamily, VoidPointer, MemAlignment>::
    check_sanity()
{
   //-----------------------
   boost::interprocess::scoped_lock<mutex_type> guard(m_header);
   //-----------------------
   imultiset_iterator ib(m_header.m_imultiset.begin()), ie(m_header.m_imultiset.end());

   size_type free_memory = 0;

   //Iterate through all blocks obtaining their size
   for(; ib != ie; ++ib){
      free_memory += (size_type)ib->m_size*Alignment;
      algo_impl_t::assert_alignment(&*ib);
      if(!algo_impl_t::check_alignment(&*ib))
         return false;
   }

   //Check allocated bytes are less than size
   if(m_header.m_allocated > m_header.m_size){
      return false;
   }

   size_type block1_off  =
      priv_first_block_offset_from_this(this, m_header.m_extra_hdr_bytes);

   //Check free bytes are less than size
   if(free_memory > (m_header.m_size - block1_off)){
      return false;
   }
   return true;
}

现在,当这种情况发生时,我的解决方案是删除共享内存并重新启动这两个进程,以便第一个进程将创建一个新的有效共享内存。

##Edit

我使用的是Boost版本1.74。

一个过程是读者,另一个过程是作者:

代码语言:javascript
复制
typedef boost::circular_buffer<SharedPtr, ShmemAllocator> Container;

bip::managed_shared_memory segment;

Container* createContainer(bip::managed_shared_memory &segment) {
   bip::named_mutex container_lock{bip::open_or_create, SHM_MUTEX};
   if (std::unique_lock open_lk{container_lock, std::try_to_lock}) {
      segment = bip::managed_shared_memory(bip::open_or_create, SHM_NAME, SHM_SIZE);
      return segment.find_or_construct<Container>(CONTAINER)(CONTAINER_SIZE, segment.get_segment_manager());
   } else {
      throw boost::interprocess::interprocess_exception("cannot lock for creating container shared memory");
   }
}

Container* OpenContainer(bip::managed_shared_memory &segment) {
      bip::named_mutex container_lock{bip::open_only, SHM_MUTEX};
      if (std::unique_lock open_lk{container_lock, std::try_to_lock}) {
            segment = bip::managed_shared_memory(bip::open_only, SHM_NAME);
            auto container = segment.find<Container>(CONTAINER);
            return container.first;
      } else {
            throw boost::interprocess::interprocess_exception("cannot lock for creating container shared memory");
      }
}

场景是,进程在循环中运行、停止、重新启动和使用现有的共享内存,在几次运行后偶尔会出现对齐问题,进程会被卡住。

我有两个问题:

  1. 协调问题的原因可能是什么?
  2. 是否有更好的方法来处理锁定的scoped mutex以避免阻塞的进程?
EN

回答 1

Stack Overflow用户

发布于 2022-06-13 11:27:13

崩溃后,第二个进程卡在check_sanity()函数中,在第一个进程重新启动后,他也停留在那里。

这部分是经过设计的。Boost Interprocess没有健壮互斥的便携实现(这是一个困难的问题)。

草图中的工作很常见,或者您可以在软件中使用定时的尝试锁来检测共享资源何时卡住了。

还请参阅此现象的许多其他示例:https://stackoverflow.com/search?tab=newest&q=user%3a85371%20robust%20interprocess

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72596288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档