3

我正在尝试使用 boost 中的 shared_lock 和 unique_lock 库来实现对资源的基本读写锁。但是,一些访问资源的线程可能会简单地崩溃。我想创建另一个进程,给定一个互斥锁,监视互斥锁并跟踪哪些进程锁定了资源以及每个进程锁定了多长时间。如果进程拥有锁的时间超过给定时间段,该进程还将强制进程释放其锁。

尽管 boost 锁都是作用域锁,一旦超出作用域就会自动解锁,但如果服务器崩溃,它仍然不能解决我的问题,从而将 SIGSEGV 发送到进程并杀死它。被杀死的进程不会调用它的任何析构函数,因此不会释放它持有的任何资源。

一种可能的解决方案是以某种方式在锁上设置一个计时器,以便进程在给定的锁期后被迫释放锁。尽管这违背了锁定的概念,但它在我们的案例中是有效的,因为我们可以保证如果任何进程持有锁超过,比如说 5 分钟,那么可以说该进程要么被杀死,要么存在陷入僵局的情况。

非常感谢任何有关如何解决此问题的建议!


由于“可能重复”,我之前的帖子已关闭,但所述重复问题没有回答我的问题。

boost:如何监控互斥锁的状态并在死锁时强制释放

4

2 回答 2

0

撇开这是否是一个好主意不谈,您可以推出自己的互斥锁实现,该实现利用共享内存来存储时间戳、进程标识符和线程标识符。

当一个线程想要锁定时,它需要在共享内存中找到一个空槽,并使用原子测试和设置操作,例如 Windows 上的 InterlockedCompareExchange,如果当前值为空值,则设置进程 ID。如果设置没有发生,则需要重新开始。在设置了进程id之后,线程需要为线程标识符重复该进程,然后对时间戳做同样的事情(它不能只是设置它,它仍然需要原子地完成)。

然后线程将需要检查所有其他已填充的插槽以确定它是否具有最低时间戳。如果不是,它需要记下具有最低时间戳的插槽,并对其进行轮询,直到它被清空、具有更高的时间戳或已超时。然后重复冲洗,直到线程拥有具有最旧时间戳的插槽,此时线程已获得锁。

如果另一个槽已经超时,线程应该触发超时处理程序(这可能会杀死另一个进程或只是在带有锁的线程中引发异常),然后使用原子测试和设置操作来清除槽。

当带有锁的线程解锁时,它会使用原子测试和设置操作来清除其插槽。

更新:还需要处理最低时间戳之间的联系以避免可能的死锁,并且处理该问题需要避免产生竞争条件。

于 2012-11-13T06:02:39.823 回答
0

@Arno:我不同意软件需要如此强大以至于它不应该首先崩溃。容错系统(想想可用性的 5 个九),需要在关键流程突然终止时进行恢复。有点意思pthread_mutexattr_*robust

保存所有者 pid,互斥锁的最后使用时间戳应该有助于恢复。

于 2012-11-28T07:05:43.953 回答