增强进程间互斥并检查是否放弃 [英] Boost interprocess mutexes and checking for abandonment

查看:53
本文介绍了增强进程间互斥并检查是否放弃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要围绕一个硬件进行进程间同步.因为此代码将需要在Windows和Linux上运行,所以我将使用Boost Interprocess互斥体进行包装.一切正常,接受我检查互斥量放弃的方法.有可能发生这种情况,因此我必须为此做好准备.

I have a need for interprocess synchronization around a piece of hardware. Because this code will need to work on Windows and Linux, I'm wrapping with Boost Interprocess mutexes. Everything works well accept my method for checking abandonment of the mutex. There is the potential that this can happen and so I must prepare for it.

我已经在测试中放弃了互斥锁,而且可以肯定的是,当我使用scoped_lock锁定互斥锁时,该进程会无限期地阻塞.我发现解决此问题的方法是通过使用scoped_lock上的超时机制(因为谷歌搜索花费大量时间来解决这个问题并没有真正显示出来,由于可移植性原因,boost对此并没有做太多事情).

I've abandoned the mutex in my testing and, sure enough, when I use scoped_lock to lock the mutex, the process blocks indefinitely. I figured the way around this is by using the timeout mechanism on scoped_lock (since much time spent Googling for methods to account for this don't really show much, boost doesn't do much around this because of portability reasons).

事不宜迟,这就是我所拥有的:

Without further ado, here's what I have:

#include <boost/interprocess/sync/named_recursive_mutex.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>

typedef boost::interprocess::named_recursive_mutex MyMutex;
typedef boost::interprocess::scoped_lock<MyMutex> ScopedLock;

MyMutex* pGate = reinterpret_cast<MyMutex*>(new MyMutex(boost::interprocess::open_or_create, "MutexName");

{
    // ScopedLock lock(*pGate); // this blocks indefinitely
    boost::posix_time::ptime timeout(boost::posix_time::microsec_clock::local_time() + boost::posix_time::seconds(10));
    ScopedLock lock(*pGate, timeout); // a 10 second timeout that returns immediately if the mutex is abandoned ?????
    if(!lock.owns()) {
        delete pGate;
        boost::interprocess::named_recursive_mutex::remove("MutexName");
        pGate = reinterpret_cast<MyMutex*>(new MyMutex(boost::interprocess::open_or_create, "MutexName");
    }
}

至少是这个主意.三个有趣的观点:

That, at least, is the idea. Three interesting points:

  • 当我使用超时对象并且互斥锁被放弃时,ScopedLock ctor会无限期阻塞.这是预期的.
  • 当我使用超时并且互斥锁被放弃时,ScopedLock ctor立即返回并告诉我它不拥有该互斥锁.好的,也许这很正常,但是为什么它也不能等待我告诉的10秒钟呢?
  • 当互斥锁未被放弃,并且我使用了超时时,ScopedLock ctor仍然会立即返回,告诉我它无法锁定或获取互斥锁的所有权,我去了通过删除互斥量并对其进行重新制作的动作.这根本不是我想要的.
  • When I don't use the timeout object, and the mutex is abandoned, the ScopedLock ctor blocks indefinitely. That's expected.
  • When I do use the timeout, and the mutex is abandoned, the ScopedLock ctor returns immediately and tells me that it doesn't own the mutex. Ok, perhaps that's normal, but why isn't it waiting for the 10 seconds I'm telling it too?
  • When the mutex isn't abandoned, and I use the timeout, the ScopedLock ctor still returns immediately, telling me that it couldn't lock, or take ownership, of the mutex and I go through the motions of removing the mutex and remaking it. This is not at all what I want.

那么,在使用这些对象时我缺少什么呢?也许它正盯着我,但我看不到它,所以我正在寻求帮助.

So, what am I missing on using these objects? Perhaps it's staring me in the face, but I can't see it and so I'm asking for help.

我还应该提到,由于该硬件的工作原理,如果该进程无法在10秒内获得互斥锁的所有权,则将放弃该互斥锁.实际上,我可能只需要等待50或60毫秒,但是10秒钟是慷慨的舍入"值.

I should also mention that, because of how this hardware works, if the process cannot gain ownership of the mutex within 10 seconds, the mutex is abandoned. In fact, I could probably wait as little as 50 or 60 milliseconds, but 10 seconds is a nice "round" number of generosity.

我正在使用Visual Studio 2010在Windows 7上进行编译.

I'm compiling on Windows 7 using Visual Studio 2010.

谢谢, 安迪

推荐答案

当我不使用超时对象并且互斥锁被放弃时,ScopedLock ctor会无限期地阻塞.这是预期的

When I don't use the timeout object, and the mutex is abandoned, the ScopedLock ctor blocks indefinitely. That's expected

针对您问题的最佳解决方案是,boost是否支持健壮的互斥锁.但是,Boost当前不支持健壮的互斥锁.只有一种计划可以模拟健壮的互斥体,因为只有linux对此具有本机支持.该仿真仍然是由图书馆作者Ion Gaztanaga计划的. 检查此链接,以了解可能将垃圾互斥锁入侵到boosts库中: http://boost. 2283326.n4.nabble.com/boost-interprocess-gt-1-45-robust-mutexes-td3416151.html

The best solution for your problem would be if boost had support for robust mutexes. However Boost currently does not support robust mutexes. There is only a plan to emulate robust mutexes, because only linux has native support on that. The emulation is still just planned by Ion Gaztanaga, the library author. Check this link about a possible hacking of rubust mutexes into the boost libs: http://boost.2283326.n4.nabble.com/boost-interprocess-gt-1-45-robust-mutexes-td3416151.html

与此同时,您可能会尝试在共享段中使用原子变量.

Meanwhile you might try to use atomic variables in a shared segment.

还要看一下这个stackoverflow条目: 如何获取废弃者的所有权boost :: interprocess :: interprocess_mutex?

Also take a look at this stackoverflow entry: How do I take ownership of an abandoned boost::interprocess::interprocess_mutex?

当我使用超时并且互斥锁被放弃时,ScopedLock ctor立即返回并告诉我它不拥有该互斥锁.好的,也许这很正常,但是为什么它也不能等待我告诉的10秒钟呢?

When I do use the timeout, and the mutex is abandoned, the ScopedLock ctor returns immediately and tells me that it doesn't own the mutex. Ok, perhaps that's normal, but why isn't it waiting for the 10 seconds I'm telling it too?

这很奇怪,您不应该得到这种行为.然而: 定时锁可能是根据try锁实现的.查看此文档: http://www. boost.org/doc/libs/1_53_0/doc/html/boost/interprocess/scoped_lock.html#idp57421760-bb 这意味着定时锁定的实现可能会在内部引发异常,然后返回false.

This is very strange, you should not get this behavior. However: The timed lock is possibly implemented in terms of the try lock. Check this documentation: http://www.boost.org/doc/libs/1_53_0/doc/html/boost/interprocess/scoped_lock.html#idp57421760-bb This means, the implementation of the timed lock might throw an exception internally and then returns false.

inline bool windows_mutex::timed_lock(const boost::posix_time::ptime &abs_time)
{
   sync_handles &handles =
      windows_intermodule_singleton<sync_handles>::get();
   //This can throw
   winapi_mutex_functions mut(handles.obtain_mutex(this->id_));
   return mut.timed_lock(abs_time);
}

可能因为没有获得互斥锁而无法获得句柄.

Possibly, the handle cannot be obtained, because the mutex is abandoned.

当互斥锁没有被放弃并且我使用超时时,ScopedLock ctor仍会立即返回,告诉我它无法锁定或拥有该互斥锁,我将进行删除互斥锁的动作.并重新制作它.这根本不是我想要的.

When the mutex isn't abandoned, and I use the timeout, the ScopedLock ctor still returns immediately, telling me that it couldn't lock, or take ownership, of the mutex and I go through the motions of removing the mutex and remaking it. This is not at all what I want.

我不确定这一点,但是我认为指定的互斥锁是通过使用共享内存来实现的.如果您使用的是Linux,请检查文件/dev/shm/MutexName.在Linux中,无论您是否已通过以下方式删除文件本身,文件描述符在被关闭之前一直保持有效. boost :: interprocess :: named_recursive_mutex :: remove.

I am not sure about this one, but I think the named mutex is implemented by using a shared memory. If you are using Linux, check for the file /dev/shm/MutexName. In Linux, a file descriptor remains valid until that is not closed, no matter if you have removed the file itself by e.g. boost::interprocess::named_recursive_mutex::remove.

这篇关于增强进程间互斥并检查是否放弃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆