从shm_open手册页:
一个新的共享内存对象最初的长度为零。可以使用 ftruncate(2) 设置对象的大小。[...] shm_open() 函数本身不会创建指定大小的共享对象,因为这样做会复制一个现有函数,该函数设置文件描述符引用的对象的大小。
这不会将应用程序暴露给竞争条件吗?考虑以下伪代码:
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_openandftruncate调用(一起)不是原子的,因此您可能有一个竞争条件,即一个进程调用shm_open(CREATEcase),但在调用之前ftruncate,另一个进程调用shm_open(GET_EXISTINGcase)并尝试mmap0 大小的对象,甚至可能写入它。
我可以想出两种方法来避免这种竞争条件:
使用 IPC 互斥体/信号量使整个事物同步,或者...
如果它是安全的(根据 POSIX),请
ftruncate同时调用CREATE和GET_EXISTING情况。
避免这种竞争条件的首选方法是什么?