Viv*_*vek 15 c c++ linux mutex shared-memory
假设进程正在共享内存中创建互斥锁并锁定它并在互斥锁被锁定时转储核心.
现在在另一个过程中,如何检测互斥锁已被锁定但不属于任何进程?
Rob*_*sak 31
似乎确切的答案是以强大的互斥体的形式提供的.
根据POSIX,可以使用pthread_mutexattr_setrobust()初始化pthread互斥锁.如果持有互斥锁的进程随后死亡,则获取它的下一个线程将接收EOWNERDEAD(但仍然成功获取互斥锁),以便它知道执行任何清理.然后,它需要使用pthread_mutex_consistent()通知所获取的互斥锁再次一致.
显然你需要内核和libc支持才能工作.在Linux上,这背后的内核支持称为"健壮的futexes",我发现对glibc HEAD应用的用户空间更新的引用.
实际上,至少在Linux世界中,对此的支持似乎还没有过滤掉.如果这些函数不可用,你可能会在那里找到pthread_mutexattr_setrobust_np(),据我所知,它似乎是一个提供相同语义的非POSIX前身.我在Solaris文档和Debian上的/usr/include/pthread.h中都找到了对pthread_mutexattr_setrobust_np()的引用.
可在此处找到POSIX规范:http://www.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setrobust.html
基于文件的锁定(使用flock(2))怎么样?当持有它的过程死亡时,它们会自动释放.
演示程序:
#include <stdio.h>
#include <time.h>
#include <sys/file.h>
void main() {
FILE * f = fopen("testfile", "w+");
printf("pid=%u time=%u Getting lock\n", getpid(), time(NULL));
flock(fileno(f), LOCK_EX);
printf("pid=%u time=%u Got lock\n", getpid(), time(NULL));
sleep(5);
printf("pid=%u time=%u Crashing\n", getpid(), time(NULL));
*(int *)NULL = 1;
}
Run Code Online (Sandbox Code Playgroud)
输出(为了清楚起见,我已经截断了PID并稍微调整一下):
$ ./a.out & sleep 2 ; ./a.out
[1] 15
pid=15 time=137 Getting lock
pid=15 time=137 Got lock
pid=17 time=139 Getting lock
pid=15 time=142 Crashing
pid=17 time=142 Got lock
pid=17 time=147 Crashing
[1]+ Segmentation fault ./a.out
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
会发生什么是第一个程序获得锁定并开始睡眠5秒钟.2秒后,程序的第二个实例启动,在尝试获取锁定时阻塞.3秒后,第一个程序段错误(bash直到稍后才告诉你)并且立即,第二个程序获得锁定并继续.