从shm_open手册页:
A new shared memory object initially has zero length. The size of the
object can be set using ftruncate(2). […] The shm_open() function
itself does not create a shared object of a specified size because
doing so would duplicate an extant function that sets the size of an
object referenced by a file descriptor.
这不会使应用程序暴露于竞争条件吗?考虑以下伪代码:
int fd = shm_open("/foo", CREATE);
if ( fd is valid ) {
// created shm object, so set its size
ftruncate(fd, 128);
} else {
fd = shm_open("/foo", GET_EXISTING);
}
void* mem = mmap(fd, 128);
由于shm_open和ftruncate调用(一起)不是原子的,你可能有一个竞争条件,一个进程调用shm_open(CREATE case)但是,在调用ftruncate之前,另一个进程调用shm_open(GET_EXISTING case)并尝试mmap对象为0大小,甚至可能写入它.
我可以想到两种避免这种竞争条件的方法:
>使用IPC互斥锁/信号量使整个事物同步,或者……
>如果它是安全的(按POSIX),请在CREATE和GET_EXISTING情况下调用ftruncate.
哪种方法可以避免这种竞争条件?
解决方法:
你的方法(从两者调用ftruncate)应该可行,但是你需要一种方法来同步使用共享内存段的内容.由于内存最初是空的(零填充),因此不包含有效的同步对象,除非您要使用atomics自行滚动,否则无论如何都需要辅助形式的同步来控制对共享内存的访问.
我认为通常情况下,您不希望多个流程竞争创建或打开具有固定名称的共享内存段,您希望拥有一个负责创建具有随机名称的段的所有者进程,使用O_EXCL来避免随机或恶意冲突,然后传递名称,一旦您成功打开它,将其大小,并在其中创建同步对象,到其他需要访问它的进程.