提升了named_mutex和remove()命令

时间:2011-09-26 12:43:45

标签: c++ boost locking mutex interprocess

我有一个可以由多个线程创建的类。但是在一个函数中需要保护代码,所以我决定使用boost interprocess互斥。每个类在其构造函数中创建或打开相同的Mutex:

MyClass::MyClass()
{
       boost::interprocess::named_mutex m_Lock(
                 boost::interprocess::open_or_create, "myLock" );
}

所以现在有一个关键代码部分被调用的地方:

int MyClass::MyFunction()
{
       boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(
                  m_Lock, boost::interprocess::try_to_lock);
       if(!lock)
       {
           return -1;
       }
       // else do some stuff here 
}

要在函数之后清理(和它在boost页面上描述的那样),我在我的类析构函数中使用remove命令:

MyClass::~MyClass()
{
       boost::interprocess::named_mutex::remove("myLock");
}

实际上所有这些代码都运行良好,但我有一个问题:

正如删除命令的说明中所述:

  

从系统中删除命名的互斥锁。错误时返回false。永远不要扔。

这意味着删除命令只是将Mutex删除出系统 - 即使另一个线程刚刚锁定它(我已经尝试过这种情况 - 它已经不再被锁定了)。 所以我的问题如下: 例如,我有3个线程(A,B和C) - 现在发生以下情况:

  1. 进程A创建类的实例,调用函数并锁定它
  2. 进程B创建类的实例,调用函数但无法访问代码(然后等待例如)
  3. 进程A使用受保护的代码完成并解锁
  4. 进程B获得对受保护代码的访问权并将其锁定
  5. 进程A删除类的实例 - &gt; remove命令叫做
  6. 进程C创建类的实例,调用函数并可以访问代码,因为remove命令删除了Mutex - &gt;错误!
  7. 所以现在有人可能会说“那就不要打电话了!” - 那可能吗?我的意思是,因为named_mutex写入系统,我怀疑它是否在没有显式调用的情况下被删除,即使程序结束。 有人有帮助吗?

3 个答案:

答案 0 :(得分:6)

来自boost docsremove来电是不必要的。 named_mutex的析构函数将自动注意向OS指示该进程不再需要该资源。只需依靠析构函数的内置行为进行清理,你就可以了。

如果显式调用remove,则可能会导致尝试使用指定互斥锁的任何其他进程或线程在互斥锁上的任何操作上失败。根据您的使用方式的编排,这可能会导致数据争用或在其他进程中抛出崩溃/异常。

  

〜named_mutex();

     

销毁* this并指示调用过程已完成   使用资源。析构函数将释放任何系统   系统为此过程分配的资源   资源。调用open时,仍然可以再次打开资源   构造函数重载。从系统中删除资源使用   除去()。

答案 1 :(得分:0)

您可能需要互斥锁的共享使用计数器。锁定析构函数中的互斥锁,递减它,如果在递减后它为零,则取消分配仍然锁定的互斥锁。你将通过它来防止你当前的竞争状态。

答案 2 :(得分:-1)

根据boost手册:

  1. 这是一个具有全局名称的互斥锁,因此可以在不同的进程中找到它。但是,该互斥锁不能放在共享内存中。 @Toby
  2. 析构函数将为系统分配由系统分配的所有系统资源,以供此进程使用。仍然可以再次调用open构造函数重载来打开资源。要从系统中删除资源,请使用remove()。

我认为以上内容应该已经解决了您的问题。