5

假设共享的 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

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

例如,我可以想象一个 PTHREADS 实现,它将在进程内的某处存储指向锁定互斥锁的指针。如果互斥锁被配置为健壮的(PTHREAD_MUTEX_ROBUST),如果进程在互斥锁被锁定时终止,它将允许实现将互斥锁标记为“已放弃”。

我不知道这样的方案是否真的有效,是否被 POSIX 允许,或者互斥鲁棒性如何在任何平台上实际实现,但如果按照这些思路的实现可行,并且根据 POSIX 有效,那么上面的重新映射场景将具有未定义的行为。

4

1 回答 1

2

不!

正如@Celada 所指出的,Linux 中健壮互斥锁的实现假定锁定的健壮互斥锁保持在固定地址:

http://www.kernel.org/doc/Documentation/robust-futexes.txt

由此我们可以肯定地得出结论,POSIX 允许禁止重新映射锁定的互斥锁的实现。否则 Linux 实现将是不正确的。

因此,我在问题中概述的程序应被视为不正确,并导致未定义的行为。

于 2013-02-27T20:54:16.077 回答