我在多进程、多线程环境中工作,使用存储在共享内存中的
pthread_rwlock_t
读写锁,以便所有进程都可以访问它。这是我最初初始化锁的方式:
rw_lock = (pthread_rwlock_t *) ShmemAlloc(sizeof(pthread_rwlock_t));
if(pthread_rwlock_init(rw_lock, NULL)) {
// Handle error
}
在此设置中,进程 A 获取读锁,如下所示:
lockStatus = pthread_rwlock_tryrdlock(rw_lock);
switch(lockStatus) {
case 0:
break;
case EBUSY:
for(int i = 0; i < 10000; i++) {
pg_usleep(100);
lockStatus = pthread_rwlock_tryrdlock(rw_lock);
if(!lockStatus) {
break;
}
}
if(!lockStatus) {
break;
}
case EINVAL:
default:
printf(ERROR, "COULD NOT GET SHARED LOCK");
break;
}
进程A获取读锁后,进程B尝试获取独占(写)锁:
if(pthread_rwlock_wrlock(rw_lock)) {
printf(ERROR, "COULD NOT GET EXCLUSIVE LOCK");
}
我预计一旦进程A释放读锁,进程B就会获得排它锁。 然而,我观察到了意想不到的行为:
阅读文档后,我修改了初始化以传递如下属性:
rw_lock = (pthread_rwlock_t *)ShmemAlloc(sizeof(pthread_rwlock_t));
pthread_rwlockattr_t attr;
pthread_rwlockattr_init(&attr);
pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
if(pthread_rwlock_init(rw_lock, &attr)) {
pthread_rwlockattr_destroy(&attr);
// Handle error
}
通过此更改,在进程 A 释放读锁后,进程 B 会如预期一致地获取排它锁。
PTHREAD_PROCESS_SHARED
),进程B如何知道进程A持有共享锁?是在等待某种内部机制吗?PTHREAD_PROCESS_SHARED
)中意识到锁被释放,而不是在第一个场景中? pthread
库如何向其他进程发出锁已释放的信号?任何有关
pthread_rwlock
的内部行为及其跨流程工作方式的见解将不胜感激。
- 在最初的场景中(没有
),进程B如何知道进程A持有共享锁?是不是在等待 在某些内部机制上?PTHREAD_PROCESS_SHARED
未指定或定义。 不过,据推测,它是通过查看共享内存中的锁数据结构来知道的。 在 B 认识到 A 已释放锁的情况下,它大概也以同样的方式知道这一点。 目前尚不清楚它如何知道在注意到状态变化的情况下如何查看。
- 为什么进程 B 在第二个场景(
)中意识到锁被释放,而不是在第一个场景中?如何PTHREAD_PROCESS_SHARED
库是否向其他进程发出锁已锁定的信号 被释放了?pthread
锁需要配置为跨进程使用,以便定义多个进程并发使用时的行为。 (这是支持多进程使用的 pthreads 对象的标准。)您在第二个场景中配置了锁,但不是在第一个场景中,因此您在第二个场景中根据锁的规范获得了行为,并在第一个场景中获得了未定义的行为首先。
对
的内部行为及其如何运作的任何见解 跨流程工作将不胜感激。pthread_rwlock
Pthreads 首先是一个规范。 有多种实现方式,其内部细节各不相同。 “内部是如何运作的?”对于只想使用实现的人来说很少是一个有用的问题,而且无论如何也没有通用的答案。 一般来说,您应该根据其规范专注于使用 Pthreads 等 API,而不是关注如何实现这些规范的细节。
但是,如果您坚持,您可以研究开源实现的源代码,例如 Glibc 的源代码。