强大的互斥锁不适用于共享内存
Robust mutex not working with shared memory
我正在使用此处找到的内存共享互斥锁的实现: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
为程序提供正确的行为。在 /dev/shm
中创建的 "my-mutex" 文件似乎保存了我在之前尝试中使用的互斥锁实例,其中不包括我后来更改的可靠设置。删除它和 运行 上述函数使其成为 return OWNERDEAD 并且进程能够锁定互斥量。
The mutex object referenced by mutex shall be locked by a call to
pthread_mutex_lock()
that returns zero or [EOWNERDEAD]
.
您没有正确处理 [OWNERDEAD]
return 代码,因此您错过了互斥体的重新锁定。
有关应如何处理的更多信息:
If mutex is a robust mutex and the owning thread terminated while
holding the mutex lock, a call to pthread_mutex_lock()
may return
the error value [EOWNERDEAD]
even if the process in which the owning
thread resides has not terminated. In these cases, the mutex is locked
by the thread but the state it protects is marked as inconsistent.
The application should ensure that the state is made consistent for
reuse and when that is complete call pthread_mutex_consistent()
. If
the application is unable to recover the state, it should unlock the
mutex without a prior call to pthread_mutex_consistent()
, after
which the mutex is marked permanently unusable.
我正在使用此处找到的内存共享互斥锁的实现: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
为程序提供正确的行为。在 /dev/shm
中创建的 "my-mutex" 文件似乎保存了我在之前尝试中使用的互斥锁实例,其中不包括我后来更改的可靠设置。删除它和 运行 上述函数使其成为 return OWNERDEAD 并且进程能够锁定互斥量。
The mutex object referenced by mutex shall be locked by a call to
pthread_mutex_lock()
that returns zero or[EOWNERDEAD]
.
您没有正确处理 [OWNERDEAD]
return 代码,因此您错过了互斥体的重新锁定。
有关应如何处理的更多信息:
If mutex is a robust mutex and the owning thread terminated while holding the mutex lock, a call to
pthread_mutex_lock()
may return the error value[EOWNERDEAD]
even if the process in which the owning thread resides has not terminated. In these cases, the mutex is locked by the thread but the state it protects is marked as inconsistent. The application should ensure that the state is made consistent for reuse and when that is complete callpthread_mutex_consistent()
. If the application is unable to recover the state, it should unlock the mutex without a prior call topthread_mutex_consistent()
, after which the mutex is marked permanently unusable.