gpt4 book ai didi

c++ - boost 进程间互斥并检查放弃

转载 作者:行者123 更新时间:2023-12-01 23:43:01 24 4
gpt4 key购买 nike

我需要围绕硬件进行进程间同步。因为此代码需要在 Windows 和 Linux 上运行,所以我使用 Boost Interprocess mutex 进行包装。一切正常,接受我检查互斥体放弃的方法。这种情况有可能发生,所以我必须为此做好准备。

我在测试中放弃了互斥锁,果然,当我使用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 构造函数将无限期地阻塞。这是预料之中的。
  • 当我使用超时并且互斥体被放弃时,ScopedLock 构造函数立即返回并告诉我它不拥有该互斥体。好吧,也许这很正常,但为什么它不等待我告诉它的 10 秒呢?
  • 当互斥体没有被放弃并且我使用超时时,ScopedLock 构造函数仍然立即返回,告诉我它无法锁定互斥体或获取互斥体的所有权,然后我就继续通过删除互斥锁并重新创建它的 Action 。这根本不是我想要的。

那么,我在使用这些对象时缺少什么?也许它正盯着我的脸,但我看不到它,所以我寻求帮助。

我还应该提到,由于该硬件的工作原理,如果进程无法在 10 秒内获得互斥体的所有权,则该互斥体将被放弃。事实上,我可能会等待 50 或 60 毫秒,但 10 秒是一个很好的慷慨数字。

我正在使用 Visual Studio 2010 在 Windows 7 上进行编译。

谢谢,安迪

最佳答案

When I don't use the timeout object, and the mutex is abandoned, the ScopedLock ctor blocks indefinitely. That's expected

解决您的问题的最佳解决方案是 boost 支持强大的互斥体。然而,Boost 目前不支持健壮的互斥体。只有一个计划来模拟强大的互斥体,因为只有 Linux 对此有 native 支持。模拟仍然是由库作者 Ion Gaztanaga 刚刚计划的。检查此链接,了解可能将 rubust 互斥体侵入 boost 库: http://boost.2283326.n4.nabble.com/boost-interprocess-gt-1-45-robust-mutexes-td3416151.html

同时,您可能会尝试在共享段中使用原子变量。

另请查看此 stackoverflow 条目: How do I take ownership of an abandoned boost::interprocess::interprocess_mutex?

When I do use the timeout, and the mutex is abandoned, the ScopedLock ctor returns immediately and tells me that it doesn't own the mutex. Ok, perhaps that's normal, but why isn't it waiting for the 10 seconds I'm telling it too?

这很奇怪,你不应该出现这种行为。然而:定时锁可以通过try锁来实现。检查这个文档: 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);
}

可能无法获取句柄,因为互斥体已被废弃。

When the mutex isn't abandoned, and I use the timeout, the ScopedLock ctor still returns immediately, telling me that it couldn't lock, or take ownership, of the mutex and I go through the motions of removing the mutex and remaking it. This is not at all what I want.

我对此不太确定,但我认为命名互斥体是通过使用共享内存来实现的。如果您使用的是 Linux,请检查文件/dev/shm/MutexName。在 Linux 中,文件描述符在未关闭之前一直有效,无论您是否通过例如删除文件本身来删除文件本身。 boost::interprocess::named_recursive_mutex::remove。

关于c++ - boost 进程间互斥并检查放弃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46904024/

24 4 0