c - 强大的互斥锁不适用于共享内存
问题描述
我正在使用在这里找到的内存共享互斥锁的实现:https ://gist.github.com/yamnikov-oleg/abf61cf96b4867cbf72d
如果持有锁的进程崩溃,我担心互斥锁所有权的行为。从我的测试来看,其他进程似乎无法获得锁。我在搜索时发现了健壮互斥锁的概念,并通过更改这部分来修改代码:
// If shared memory was just initialized -
// initialize the mutex as well.
if (mutex.created) {
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr)) {
perror("pthread_mutexattr_init");
return mutex;
}
if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
perror("pthread_mutexattr_setpshared");
return mutex;
}
if (pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST)) { //Added this portion.
perror("pthread_mutexattr_setrobust");
return mutex;
}
if (pthread_mutex_init(mutex_ptr, &attr)) {
perror("pthread_mutex_init");
return mutex;
}
}
使用这些文件的代码是:
shared_mutex_t mutex = shared_mutex_init("/my-mutex");
if (mutex.ptr == NULL) return 1;
if (mutex.created) printf("The mutex was just created\n");
int i = 0;
while(1) {
int trylock = pthread_mutex_trylock(mutex.ptr);
printf("Try lock: %d\n", trylock);
if (trylock != 0) continue;
printf("I'm in\n");
if (i == 5) {
return 1 / 0;
}
sleep(5);
pthread_mutex_unlock(mutex.ptr);
sleep(1);
i++;
if (i == 10) {
break;
}
}
为了进行测试,我运行了两个程序实例并观察它们之间传递的锁所有权。当 i == 5 时,程序将中断,并且应该将所有权传递给下一次调用 lock,从我所读到的健壮互斥锁中。
但是,似乎没有任何改变,并且行为与我更改任何内容之前相同。关于如何进行的任何想法?提前致谢。
编辑:
使用pthread_mutex_trylock
为程序提供正确的行为。似乎在其中创建的“my-mutex”文件包含/dev/shm
了我在以前的尝试中使用的互斥锁的实例,其中不包括我后来更改的健壮设置。删除它并使用上述函数运行使其返回 OWNERDEAD 并且进程能够锁定互斥锁。
解决方案
文档说:
由 mutex 引用的 mutex 对象应通过
pthread_mutex_lock()
返回零或的调用来锁定[EOWNERDEAD]
。
您没有[OWNERDEAD]
正确处理返回代码,因此您错过了互斥锁的重新锁定。
有关如何处理的更多信息:
如果互斥锁是一个健壮的互斥锁并且拥有线程在持有互斥锁时终止,则即使拥有线程所在的进程尚未终止,调用也
pthread_mutex_lock()
可能返回错误值。[EOWNERDEAD]
在这些情况下,互斥锁被线程锁定,但它保护的状态被标记为不一致。应用程序应确保状态保持一致以便重用以及何时完成调用pthread_mutex_consistent()
。如果应用程序无法恢复状态,它应该在没有事先调用的情况下解锁互斥锁pthread_mutex_consistent()
,之后互斥锁被标记为永久不可用。
推荐阅读
- vba - 将日期格式 dd/mm/yyyy 更改为 mm/dd/yyyy
- hibernate - Hibernate Envers 'forEntitiesAtRevision' 生成冗余子查询
- python - 如何在同一个交互式图形上绘制两条线?
- azure-devops - YAML for Azure Pipeline for MonoRepo 代码在自托管代理上
- javascript - How to use a mapped value in a function call?
- html - 隐藏其中一些元素后自动重新排序引导元素
- vb.net - 图表系列透明背景
- node.js - 将猫鼬查询结果推送到全局数组
- android - 如何在另一个 ViewPager2 中使用 ViewPager2
- java - 在java类中使用表作为属性