Unix 为什么System V共享内存有单独的获取和附加功能?
使用System V shared memory IPC需要调用以下两个函数:Unix 为什么System V共享内存有单独的获取和附加功能?,unix,posix,ipc,shared-memory,Unix,Posix,Ipc,Shared Memory,使用System V shared memory IPC需要调用以下两个函数: int shmget(key_t key, size_t size, int shmflg); void *shmat(int shmid, const void *shmaddr, int shmflg); 为什么它们被设计为独立的,而不是只有一个函数接受这些参数,同时执行两个函数并简单地返回地址 我们可以把文件看作类比。在字符串(文件路径)上的code>open为我们提供了一个文件描述符,我们使用它来读取/写入
int shmget(key_t key, size_t size, int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
为什么它们被设计为独立的,而不是只有一个函数接受这些参数,同时执行两个函数并简单地返回地址
我们可以把文件看作类比。在字符串(文件路径)上的code>open为我们提供了一个文件描述符,我们使用它来读取/写入文件。完成后,我们将关闭文件描述符上的。这种设计看起来很自然,我们不必用字符串打开
来获取描述符,然后将
附加到描述符上
作为一个例子,我有什么想法,看看
POSIX共享内存中也存在这种分离(
shm_-open
和mmap
),但原因是mmap
在shm_-open
实现之前就存在并且可以重用,mmap
需要一个描述符(来源:UNIX网络编程第2卷,R.Stevens,第13章,第326页).共享内存可能是允许IPC的最快方式之一,因为数据不需要复制,但与之相关的问题是同步多个线程之间的访问。您可以使用信号量或记录锁来实现这一点,我们最终会在unix中使用稍后的fro共享内存,尽管它们没有简单的那么高效,系统清理得很好,并且您不需要信号量带来的一些光环。
让我们看看这些是如何工作的,以了解它们为什么会这样实现
linux内核()使用的shmid_ds也随之出现
shm_Natch是当前连接的无符号整数计数器。shmget为您获取一个shm id,并设置诸如ipc_perm、日期、pid、atime-ctime、段大小请求(shm_-segsz)之类的内容
接下来,shmctl开始使用ipc_STAT、ipc_RMID、ipc_SET为ipc做一些事情,比如设置perms、获取或删除某个段的shm_id,甚至锁定或解锁它
一旦段准备就绪,进程将使用shmat附加到其地址空间,具体取决于标志和地址参数。一旦它连接内核,就会增加shm_natch。分离时,我们称shmdt为分离。标识符和相关数据结构的删除不是自动进行的。某些进程必须使用IPC\u RMID调用shmctl并根据shm\u perm来完成此操作
如您所见,这与使用信号量的方式非常相似,实现也很有意义。我可能想到的一个原因是: (摘自)
- 在fork(2)之后,子级继承附加的共享内存段李>
- 执行(2)后,所有连接的共享内存段将从进程中分离李>
- 退出(2)后,所有连接的共享内存段将从进程中分离
如果它们都打包到同一个函数中,您无论如何都需要一个单独的函数,它只进行引用计数(在fork/exec期间调用)。因此,我认为这种设计只是为了促进代码重用,避免代码重复。对于文件,
fork
和exec
处理复制文件描述符和更新内核中的引用计数。文件没有“附加”。为什么shmat
会向用户公开,而它可以像文件一样在内核中完成?