Kri*_*ege 5 posix mutex mmap pthreads remap
假设共享的 POSIX 互斥锁已经初始化(使用 PTHREAD_PROCESS_SHARED)。
然后,考虑以下过程:
typedef struct {
pthread_mutex_t mutex;
// ...
} Shared;
Shared *shared = (Shared *)mmap(...); // MAP
pthread_mutex_lock(&shared->mutex); // LOCK
// REMAP
munmap(shared, ...);
shared = (Shared *)mmap(...);
pthread_mutex_unlock(&shared->mutex); // UNLOCK
Run Code Online (Sandbox Code Playgroud)
POSIX 是否保证这将按照“天真”的意图工作?
据我所知,没有一个相关的手册页提到这种情况。
另外,以下特定于 Linux 的替代方案怎么样:
Shared *shared = (Shared *)mmap(...); // MAP
pthread_mutex_lock(&shared->mutex); // LOCK
shared = (Shared *)mremap(shared, ...); // MREMAP_MAYMOVE
pthread_mutex_unlock(&shared->mutex); // UNLOCK
Run Code Online (Sandbox Code Playgroud)
例如,我可以想象一个 PTHREADS 实现,它将存储一个指向进程内某处锁定互斥锁的指针。如果互斥锁被配置为健壮的 (PTHREAD_MUTEX_ROBUST),如果进程在互斥锁被锁定时死亡,则它允许实现将互斥锁标记为“已放弃”。
我不知道是否有这样的方案实际上会工作,不管它是由POSIX,或允许如何互斥稳健性在任何平台上真正实现,但如果沿着这些路线的实现会工作,将可根据有效的POSIX,那么上面的重新映射场景将具有未定义的行为。
不!
正如 @Celada 所指出的,Linux 中鲁棒互斥体的实现假设锁定的鲁棒互斥体保留在固定地址:
http://www.kernel.org/doc/Documentation/robust-futexes.txt
由此我们可以肯定地得出结论,POSIX 允许禁止重新映射的实现映射锁定互斥体的实现。否则 Linux 的实现将会不正确。
因此,我在问题中概述的过程应该被视为不正确,并导致未定义的行为。