posix中的稳健rwlock

时间:2018-08-21 21:07:06

标签: c++ c pthreads posix

Posix提供了一种将互斥体标记为“健壮”的机制,从而允许多进程系统从持有互斥体的进程崩溃中正常恢复。

pthread_mutexattr_setrobust(&mutexattr, PTHREAD_MUTEX_ROBUST);

github.com/gitgitgadget/git

但是,rwlock(读写器锁)似乎没有等效功能。

在按住rwlock的同时,如何从崩溃的进程中正常恢复?

2 个答案:

答案 0 :(得分:1)

由于具有“并发读取器”属性,实施强大的rwlock实际上非常困难-具有有限存储空间的rwlock,但是无限制数量的并发读取器从根本上无法跟踪其读取器是谁,因此,如果了解当前读取器是谁,要保留(为了在读者死亡时减少当前的读锁定计数),必须是读者任务本身而不是rwlock知道自己的所有权,而不是rwlock。我看不到可以在健壮的互斥体之上或通常用于实现健壮的互斥体的基础机制(如Linux上的robust_list)之上构建任何明显的方式。

如果您确实需要强大的rwlock语义,最好使用某种协议,并带有专用的协调器进程,该进程假定不会死,该进程通过关闭与客户机的管道/套接字来跟踪客户机的死亡,并且能够通过共享内存内容判断死进程是否持有读取锁。请注意,这仍然涉及实现您自己的rwlock。

答案 1 :(得分:0)

  

在按住rwlock的同时,如何从崩溃的进程中正常恢复?

POSIX并未为其rwlock定义健壮性选项。如果某个进程在保持一个锁的状态下死了,则该锁无法恢复-您甚至无法pthread_rwlock_destroy。您也不能期望任何试图获取锁的被阻止的进程在它们的超时(如果有)到期之前解除锁定。无条件地尝试阻塞并且没有超时来获取锁的线程即使通过传递信号也无法解除阻塞,因为POSIX指定如果它们的等待被信号中断,则它们将在信号处理程序完成后恢复阻塞。

因此,在几个协作进程之一死于同时锁定共享rwlock的情况下,无论是读取还是写入,最好的结果可能是安排其他协作进程尽可能干净地关闭。您应该能够通过单独的监视过程来安排类似的事情,该过程会在发生锁定失败时将SIGTERM发送给其他人。尽管如此,还需要做更多的工作,可能还包括一些额外的纪律或环绕获取rwlock。

老实说,如果您想要鲁棒性,那么最好使用例如POSIX健壮互斥体和POSIX条件变量来滚动自己的读/写锁,如@R ..注释中所述。

还要考虑锁本身的健壮性只是图片的一半。如果线程在持有写锁的同时死亡,那么您还有另一个问题,那就是在继续操作之前确保受锁保护的数据的完整性。