回答
如果你在Linux或类似的东西,可考虑使用named semaphores而不是(我假设是什么)并行线程互斥。我不认为有一种方法可以确定pthreads互斥量的锁定PID,而不是构建自己的注册表并将其放入共享内存。
您应该使用操作系统提供的信号量。
操作系统释放进程已打开的所有资源,无论它是否死亡或正常退出。
并非在所有资源。如果OP按照建议使用POSIX信号量,并且持有锁的进程死亡,则信号量的值不会恢复,从而可能使其他进程死锁。 – Duck 2009-11-09 19:37:13
只有当有人会有相同的想法并且会发现这个讨论的使用时,我才会退出这个错误的帖子!
您可以使用这种方法。 1)锁定POSIX共享互斥锁 2)将进程ID保存在共享内存中。 3)解锁共享互斥 4)在正确的出口清洁过程-ID
如果进程核心转储下一过程会发现,在共享存储器中有保存在步骤#2中的进程ID。如果在操作系统中没有这个进程ID的进程,那么没有人拥有共享互斥。所以只需要替换进程ID。为了回答评论
更新:
场景1:1。 开始P1 2. P1创建/打开一个名为互斥体,如果它不存在 3. P1它timed_locks命名的互斥体和successfuly (如果需要,等待10秒); 4. P1 coredumps 5. P2在coredump后启动 6. P2创建/打开一个已命名的互斥锁,它存在,它是OK 7. P2 timed_locks已命名的互斥锁并且无法锁定(如果需要,等待10秒); 8. P2删除命名的互斥体 9. P2再现了命名的互斥体&锁定
我在这里没有看到解决方案。情况1:(1)P1锁; (2)P1死亡; (3)死锁。情景2:(1)P1锁; (2)P1写pid; (3)P1解锁; (4)P2得到控制并锁定并找到P1 pid。场景3:如果切换顺序以便在解锁和进程死亡之前清除pid,则可以回到最初的问题,即死进程持有锁并使其他进程死锁。我错过了什么吗? – Duck 2009-11-09 21:42:26
评论场景#1 – 2009-11-10 16:13:31
此更新无法使用。对任意时间的依赖是不好的。但更糟糕的是,如果超过1个进程试图执行这个公式,那么在删除,重新创建,锁定等互斥量的时候,所有地狱都可能崩溃。 – Duck 2009-11-10 21:12:37
基于文件的锁定(使用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;
}
输出(我已经截断了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
什么情况是,第一个节目获得锁,并开始睡5秒钟。 2秒后,程序的第二个实例开始在试图获取锁的同时阻塞。 3秒钟后,第一个程序段错误(bash直到后来才告诉你),第二个程序获得锁定并继续。
似乎确切的答案已经以强健的互斥体的形式提供。
根据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
我认为这是一个更好的答案。到目前为止,我一直在Solaris上使用强大的互斥锁。 – 2010-10-18 17:03:14
强大的互斥体非常棒,但请注意,如果互斥体是在父进程中创建的,然后分叉和子进程同时持有互斥锁,它们可能无法在glibc 2.15之前的GNU/Linux上正常工作。 [bug](http://sourceware.org/bugzilla/show_bug.cgi?id=13002)在glibc 2.15中修复。如果共享互斥体的两个进程不是由分叉创建的父代和子代,那么即使使用旧的glibc版本,健壮的互斥体也可以正常工作。 – 2013-01-10 23:27:52
- 1. 在C++ 98互斥锁中锁定变量共享数据互斥锁
- 2. 共享互斥锁的交替例程
- 3. 1字节共享内存需要互斥锁
- 4. C多进程访问共享内存互斥锁
- 5. pthread进程共享互斥死锁
- 6. C++崩溃中的共享内存
- 7. 写一个互斥的共享资源
- 8. 当互斥锁不够时?
- 9. C - 使用互斥锁时程序崩溃或不反应
- 10. 共享内存锁定和进程崩溃
- 11. 如何共享一组pthread的互斥锁?
- 12. C++是互斥体锁定共享资源的唯一方式
- 13. C++ pthreads - 尝试锁定互斥读取时崩溃
- 14. std ::共享内存中的互斥量不工作
- 15. 管理共享内存中的互斥量
- 16. 共享内存并发算法与互斥锁/信号量之间的关系
- 17. Android中的进程共享互斥锁和条件变量
- 18. iPhone上的“互斥”和NSCondition的共享内存
- 19. 锁定多个互斥锁
- 20. 多线程互斥锁可以使用多个互斥锁
- 21. 线程与锁定的互斥体崩溃
- 22. 调试器:如何在崩溃转储中获取“互斥锁拥有”或“无互斥锁”信息?
- 23. Win32当进程崩溃时,不会释放互斥体
- 24. 与CUDA共享内存互斥 - 增加项目
- 25. 互斥锁和锁
- 26. 锁定可共享内存
- 27. 使用dispatch_sync作为一个互斥锁
- 28. boost :: asio链vs共享互斥的
- 29. Google App Engine中的内存缓存和互斥锁?
- 30. 打开一个与服务共享的互斥体
一般同意信号量建议,但POSIX信号量并不真正解决问题,因为它们也不记录锁定过程的PID,也不会在不合时宜的死亡情况下解锁。虽然它们可能是SysV信号量,但生锈和笨拙的确会跟踪PID,并且可以在使用SEM_UNDO选项调用时恢复。 – Duck 2009-11-09 22:07:20