我的场景:一台服务器和一些客户端(虽然不多).服务器一次只能响应一个客户端,因此必须排队.我正在使用互斥(boost::interprocess::interprocess_mutex)执行此操作,包含在boost::interprocess::scoped_lock.
问题是,如果一个客户端在持有互斥锁时意外死亡(即没有析构函数运行),则其他客户端遇到麻烦,因为他们正在等待该互斥锁.我考虑过使用定时等待,所以如果我的客户端等待,比如20秒并且没有得到互斥锁,那么它就会继续与服务器通信.
这种方法的问题:1)它每次都这样做.如果它处于循环中,不断与服务器通信,则需要每次都等待超时.2)如果有三个客户端,并且其中一个客户端在持有互斥锁时死亡,则另外两个客户端将等待20秒并同时与服务器通信 - 这正是我试图避免的.
所以,我怎么能对客户说,"嘿那里,似乎这个互斥体已被抛弃,取得它的所有权"?
我需要围绕一个硬件进行进程间同步.因为这段代码需要在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上进行编译. …