gpt4 book ai didi

unix - 有没有像 shm_open() 这样没有文件名的东西?

转载 作者:行者123 更新时间:2023-12-02 02:55:16 69 4
gpt4 key购买 nike

POSIX shm_open() 函数返回可用于访问共享内存的文件描述符。这是非常方便的,因为可以使用所有控制文件描述符的传统机制来控制共享内存。

唯一的缺点是 shm_open() 总是需要一个文件名。所以我需要这样做:

// Open with a clever temp file name and hope for the best.
fd = shm_open(tempfilename, O_RDWR | O_CREAT | O_EXCL, 0600);

// Immediately delete the temp file to keep the shm namespace clean.
shm_unlink(tempfilename);

// Then keep using fd -- the shm object remains as long as there are open fds.

这种tempfilename的使用很难移植且可靠。文件名的解释(命名空间是什么,如何处理权限)因系统而异。

在许多情况下,使用共享内存对象的进程不需要文件名,因为只需将文件描述符从一个进程传递到另一个进程即可更简单、更安全地访问该对象。那么是否有类似 shm_open() 但可以在不触及共享内存文件名命名空间的情况下使用的东西?

mmap()MAP_ANON|MAP_SHARED 很棒,但它提供的不是文件描述符,而是指针。该指针无法在执行边界上保留,并且无法像文件描述符那样通过 Unix 域套接字发送到另一个进程。

默认情况下,shm_open() 返回的文件描述符也无法在执行边界后继续存在:POSIX 定义表示,设置了与新文件描述符关联的 FD_CLOEXEC 文件描述符标志但可以在 MacOS、Linux、FreeBSD、OpenBSD、NetBSD、DragonFlyBSD 以及可能的其他操作系统上使用 fcntl() 清除该标志。

最佳答案

解决问题的库

我设法写了 a library它提供了简单的界面:

int shm_open_anon(void);

该库编译时没有警告,并在 Linux、Solaris、MacOS、FreeBSD、OpenBSD、NetBSD、DragonFlyBSD 和 Haiku 上成功运行测试程序。您也许能够将其适应其他操作系统;如果您这样做,请发送拉取请求。

该库返回一个设置了 close-on-exec 标志的文件描述符。您可以使用 fcntl() 清除该标志。在所有受支持的操作系统上,这将允许您通过 exec() 传递 fd 。测试程序证明这是可行的。

库中使用的实现技术

该库的自述文件非常精确地说明了每个操作系统已完成的操作和未完成的操作。以下是主要内容的摘要。

有几个不可移植的东西或多或少相当于 shm_open()没有文件名:

  • FreeBSD 可以获取 SHM_ANON作为 shm_open() 的路径名自2008年以来。

  • Linux 有一个 memfd_create() 从内核版本 3.17 开始的系统调用。

  • 早期版本的 Linux 可以使用 mkostemp(name, O_CLOEXEC | O_TMPFILE)哪里name类似于 /dev/shm/XXXXXX 。请注意,我们没有使用 shm_open()都在这里--mkostemp()隐含地使用了一个完全普通的 open()称呼。 Linux 在 /dev/shm 中挂载了一个特殊的内存支持的文件系统但有些发行版使用 /run/shm相反,这里存在陷阱。而且您仍然需要 shm_unlink() 临时文件。

  • OpenBSD 有一个 shm_mkstemp() 从 5.4 版本开始调用。你还得shm_unlink()临时文件,但至少它很容易安全地创建。

对于其他操作系统,我执行了以下操作:

  1. 找出 POSIX 的 name 参数的依赖于操作系统的格式 shm_open() 。请注意,您可以传递的名称是绝对可移植的。例如,NetBSD 和 DragonFlyBSD 对于名称中的斜线有冲突的要求。即使您的目标是使用命名 shm 对象(PO​​SIX API 就是为此设计的)而不是匿名对象(正如我们在这里所做的那样),这也适用。

  2. 在名称中附加一些随机字母和数字(通过读取 /dev/random )。这基本上就是mktemp()确实如此,只是我们不检查文件系统中是否存在我们的随机名称。 name 参数的解释差异很大,因此没有合理的方法将其可移植地映射到实际的文件名。此外,Solaris 并不总是提供 mktemp() 。出于所有实际目的,我们输入的随机性将确保我们需要的那一小部分时间的名称是唯一的。

  3. 通过 shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600) 打开具有该名称的 shm 对象。如果我们的随机文件名已经存在的话,O_EXCL无论如何都会导致此调用失败,因此不会造成任何损害。 0600权限(所有者读写)在某些系统上是必需的,而不是空白 0权限。

  4. 立即调用shm_unlink()摆脱随机名称。文件描述符仍然供我们使用。

POSIX 不保证该技术有效,但是:

  1. shm_open() name 参数未由 POSIX 指定,因此也无法保证其他任何内容都能正常工作。
  2. 我会让上面的兼容性列表说明一切。

享受吧。

关于unix - 有没有像 shm_open() 这样没有文件名的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55704758/

69 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com