我有一个需要围绕一个硬件间同步。 因为这个代码将需要在Windows和Linux的工作,我用升压进程间互斥包装。 一切正常接受我的检查互斥的放弃方法。 还有的是,这可能发生,所以我必须为它做准备的可能性。
我已经放弃了互斥锁在我的测试,果然,当我使用scoped_lock的无限期锁定互斥,过程块。 我想解决这个问题的方法是使用上的scoped_lock超时机制(因为太多的时间花在谷歌搜索的方法来说明这一点确实不表现出很大的,升压并没有做太多解决这个因为可移植性的原因)。
事不宜迟,这里是我有:
#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");
}
}
也就是说,至少,是这个想法。 三层有趣的观点:
- 当我不使用超时对象,并互斥被放弃,在ScopedLock构造函数无限期阻塞。 这是预期。
- 当我使用超时,并互斥被放弃,在ScopedLock构造函数立即返回,并告诉我,它不拥有互斥锁。 好吧,也许这是正常的,但为什么没有等待10秒我告诉它吗?
- 当互斥没有放弃 ,我用的是超时,则ScopedLock构造函数还是立即返回,告诉我它无法锁定,或采取所有权,互斥的,我经过删除互斥和改造它的运动。 这是不是在所有我想要的东西。
所以,我错过什么关于使用这些对象呢? 也许是盯着我的脸,但我不能看到它,所以我寻求帮助。
我还要提到的是,因为这个硬件是如何工作的,如果过程不能在10秒内获得互斥体的所有权,互斥量被放弃。 事实上,我大概可以等待短短的50或60毫秒,不过10秒慷慨的一个很好的“圆”号。
我编写在Windows 7上使用Visual Studio 2010。
谢谢,安迪
当我不使用超时对象,并互斥被放弃,在ScopedLock构造函数无限期阻塞。 这是预期
您的问题最好的解决办法是,如果有提升的鲁棒互斥支持。 然而升压目前不支持强大的互斥。 只有仿效强大的互斥体,因为只有Linux已经对本机支持的计划。 该仿真还只是通过离子Gaztanaga,图书馆笔者计划。 检查有关rubust互斥体的一个可能的黑客攻击此链接到升压库: http://boost.2283326.n4.nabble.com/boost-interprocess-gt-1-45-robust-mutexes-td3416151.html
同时,你可以尝试在一个共享网段使用原子变量。
也看看这个计算器条目: 我如何采取一个废弃的boost ::进程间:: interprocess_mutex的所有权?
当我使用超时,并互斥被放弃,在ScopedLock构造函数立即返回,并告诉我,它不拥有互斥锁。 好吧,也许这是正常的,但为什么没有等待10秒我告诉它吗?
这是很奇怪的,你不应该得到这个行为。 但是:该定时锁可能是在尝试锁定的条件来实现。 检查此文件: http://www.boost.org/doc/libs/1_53_0/doc/html/boost/interprocess/scoped_lock.html#idp57421760-bb这意味着,定时锁定的实现可能在内部抛出一个异常然后返回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);
}
可能的话,不能得到这个句柄,因为互斥量被放弃。
当互斥没有放弃,我用的是超时,则ScopedLock构造函数还是立即返回,告诉我它无法锁定,或采取所有权,互斥的,我经过删除互斥和改造它的运动。 这是不是在所有我想要的东西。
我不知道这一个,但我认为命名的mutex是通过使用共享内存来实现。 如果您使用的是Linux,请检查文件/ dev / shm的/ MutexName。 在Linux中,文件描述符仍然有效,直到没有关闭,如果您已删除例如通过提升文件本身无论::进程间:: named_recursive_mutex ::删除。
退房BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING和BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS编译标志。 定义第一个符号在你的代码,迫使间互斥超时和第二符号定义的超时时间。
我帮助,让他们添加到库,解决了放弃的互斥体的问题。 有必要将其添加由于依赖于简单的互斥体,而不是定时互斥多间结构(如message_queue)。 有可能在未来更强大的解决方案,但这种解决方案的工作只是罚款,我需要间。
对不起,我不能帮你的代码的那一刻; 一些工作不正常那里。
BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING也不是那么好。 它抛出一个异常,并没有太大的帮助。 要解决异常行为我写了这个宏。 它的工作原理只是不行了常见望目。 在此示例中named_mutex被使用。 宏创建一个有超时范围的锁,如果锁不能被收购的特殊原因,它会之后解锁。 通过这种方式,程序可以稍后再锁定,并不会冻结或立即崩溃。
#define TIMEOUT 1000
#define SAFELOCK(pMutex) \
boost::posix_time::ptime wait_time \
= boost::posix_time::microsec_clock::universal_time() \
+ boost::posix_time::milliseconds(TIMEOUT); \
boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock(*pMutex, wait_time); \
if(!lock.owns()) { \
pMutex->unlock(); }
但是,即使这不是最佳的,因为代码被锁定现在运行解锁一次。 这可能会导致问题。 您可以轻松地扩展但宏。 例如,仅运行如果lock.owns()是正确的代码。
提高::进程间:: named_mutex有3认定中:在Windows中,您可以使用宏来使用Windows互斥的,而不是提升互斥,你可以尝试捕捉废弃的异常,你应该解开了!
在Linux上,提升了pthread_mutex,但它在1_65_1version没有强健属性
所以我实现了自己interprocess_mutex使用系统API(窗口互斥和Linux pthread_mutex过程中共享模式),但Windows互斥锁在内核,而不是文件。