我需要围绕一块硬件进行进程间同步。因为此代码需要在 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 上进行编译。
谢谢,安迪