【发布时间】:2013-03-24 06:12:05
【问题描述】:
我需要围绕一个硬件进行进程间同步。因为此代码需要在 Windows 和 Linux 上运行,所以我使用 Boost Interprocess 互斥锁进行包装。一切正常,接受我检查放弃互斥锁的方法。有可能发生这种情况,所以我必须做好准备。
我在测试中放弃了互斥锁,果然,当我使用 scoped_lock 锁定互斥锁时,进程无限期地阻塞。我想解决这个问题的方法是在 scoped_lock 上使用超时机制(因为花费大量时间在谷歌上搜索解决这个问题的方法并没有真正显示出太多,由于可移植性的原因,boost 并没有做太多的事情)。
事不宜迟,这就是我所拥有的:
#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 = 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 = new MyMutex(boost::interprocess::open_or_create, "MutexName");
}
}
至少,这是一个想法。三个有趣的点:
- 当我不使用超时对象并放弃互斥锁时,ScopedLock ctor 会无限期地阻塞。这是意料之中的。
- 当我确实使用超时并且互斥体被放弃时,ScopedLock ctor 立即返回并告诉我它不拥有互斥体。好吧,也许这很正常,但它为什么不等我告诉它的 10 秒呢?
- 当互斥锁没有被放弃,并且我使用超时时,ScopedLock ctor 仍然立即返回,告诉我它无法锁定或获取互斥锁的所有权,然后我就走了通过删除互斥体并重新制作它的动作。这根本不是我想要的。
那么,我在使用这些对象时缺少什么?也许它正盯着我的脸,但我看不到它,所以我在寻求帮助。
我还应该提到,由于该硬件的工作原理,如果进程无法在 10 秒内获得互斥锁的所有权,则该互斥锁将被放弃。事实上,我可能只需要等待 50 或 60 毫秒,但 10 秒是一个不错的“整数”慷慨数字。
我正在使用 Visual Studio 2010 在 Windows 7 上进行编译。
谢谢, 安迪
【问题讨论】:
-
与您的问题无关,但您的示例中的
reinterpret_cast<MyMutex*>s 不需要(不确定它们为什么存在)。 -
@GaborMarton 我认为我正确使用了 remove() 函数。再次检查代码。我正在删除指针,我同意它不会删除互斥锁,但是我确实调用了 boost::interprocess::named_recursive_mutex::remove("MyMutex")。如果我错误地使用它,请纠正我。谢谢
-
检查this。它是原始强大的互斥体仿真的演变。
-
我可能是错的,但根据我的经验,当进程间锁被放弃时,你唯一的希望就是关闭一切并退出。希望您可以在重新启动时恢复任何丢失的状态。换句话说,不要费心尝试继续运行。您的共享状态可能完全错误。
-
有点晚了,但是对于其他走这条路的人,您需要使用universal_time()而不是local_time()。锁定超时是绝对 UTC 时间点。