我需要围绕一个硬件进行进程间同步.因为这段代码需要在Windows和Linux上运行,所以我使用Boost Interprocess互斥锁.一切正常,请接受我检查放弃互斥锁的方法.这种情况有可能发生,所以我必须做好准备.
我在测试中放弃了互斥锁,当然,当我使用scoped_lock来锁定互斥锁时,进程会无限期地阻塞.我想通过在scoped_lock上使用超时机制来解决这个问题(因为Googling花费了大量时间来解决这个问题并没有真正显示出来,因为可移植性原因,提升并没有做太多事情).
不用多说,这就是我所拥有的:
#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");
}
}
Run Code Online (Sandbox Code Playgroud)
这至少就是这个想法.三个有趣的观点:
那么,我在使用这些对象时缺少什么?也许它正盯着我看,但我看不到它,所以我在寻求帮助.
我还应该提一下,由于这个硬件的工作方式,如果进程无法在10秒内获得互斥锁的所有权,则互斥量将被放弃.事实上,我可能只需要等待50或60毫秒,但10秒是一个很好的"圆"数量的慷慨.
我正在使用Visual Studio 2010在Windows 7上进行编译.
谢谢,安迪
当我不使用超时对象,并且放弃互斥锁时,ScopedLock ctor会无限期地阻塞.这是预期的
解决问题的最佳方案是如果boost能够支持强大的互斥锁.但是Boost目前不支持强大的互斥锁.只有一个计划来模拟强大的互斥锁,因为只有linux才有本机支持.模拟仍然只是图书馆作者Ion Gaztanaga的计划.查看此链接,了解可能将rubust互斥锁入到升级库中:http://boost.2283326.n4.nabble.com/boost-interprocess-gt-1-45-robust-mutexes-td3416151.html
同时,您可能会尝试在共享段中使用原子变量.
另请查看此stackoverflow条目: 如何获取已废弃的boost :: interprocess :: interprocess_mutex的所有权?
当我使用超时,并且放弃互斥锁时,ScopedLock ctor立即返回并告诉我它不拥有互斥锁.好吧,也许这是正常的,但为什么不等待我告诉它的10秒呢?
这很奇怪,你不应该得到这种行为.但是:定时锁可能是根据try lock实现的.请查看此文档: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);
}
Run Code Online (Sandbox Code Playgroud)
可能无法获得手柄,因为互斥体被放弃了.
当互斥锁没有被放弃,并且我使用超时时,ScopedLock ctor仍然立即返回,告诉我它无法锁定或获取互斥锁的所有权,我会通过移除互斥锁并重新制作它的动作.这根本不是我想要的.
我不确定这个,但我认为命名互斥是通过使用共享内存实现的.如果您使用的是Linux,请检查文件/ dev/shm/MutexName.在Linux中,文件描述符保持有效直到未关闭,无论您是否通过例如boost :: interprocess :: named_recursive_mutex :: remove删除了文件本身.
小智 5
查看BOOST_INTERPROCESS_ENABLE_TIMEOUT_WHEN_LOCKING和BOOST_INTERPROCESS_TIMEOUT_WHEN_LOCKING_DURATION_MS编译标志。定义代码中的第一个符号以强制进程间互斥锁超时,定义第二个符号以定义超时持续时间。
我帮助将它们添加到库中以解决废弃的互斥锁问题。由于许多进程间构造(如 message_queue)依赖于简单互斥而不是定时互斥,因此有必要添加它。未来可能会有更强大的解决方案,但这个解决方案已经很好地满足了我的进程间需求。
很抱歉,我目前无法帮助您处理代码;有些东西在那里工作不正常。
| 归档时间: |
|
| 查看次数: |
4274 次 |
| 最近记录: |