- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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()
临时文件,但至少它很容易安全地创建。
对于其他操作系统,我执行了以下操作:
找出 POSIX 的 name 参数的依赖于操作系统的格式 shm_open()
。请注意,您可以传递的名称是绝对可移植的。例如,NetBSD 和 DragonFlyBSD 对于名称中的斜线有冲突的要求。即使您的目标是使用命名 shm 对象(POSIX API 就是为此设计的)而不是匿名对象(正如我们在这里所做的那样),这也适用。
在名称中附加一些随机字母和数字(通过读取 /dev/random
)。这基本上就是mktemp()
确实如此,只是我们不检查文件系统中是否存在我们的随机名称。 name 参数的解释差异很大,因此没有合理的方法将其可移植地映射到实际的文件名。此外,Solaris 并不总是提供 mktemp()
。出于所有实际目的,我们输入的随机性将确保我们需要的那一小部分时间的名称是唯一的。
通过 shm_open(name, O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600)
打开具有该名称的 shm 对象。如果我们的随机文件名已经存在的话,O_EXCL
无论如何都会导致此调用失败,因此不会造成任何损害。 0600
权限(所有者读写)在某些系统上是必需的,而不是空白 0
权限。
立即调用shm_unlink()
摆脱随机名称。文件描述符仍然供我们使用。
POSIX 不保证该技术有效,但是:
shm_open()
name 参数未由 POSIX 指定,因此也无法保证其他任何内容都能正常工作。享受吧。
关于unix - 有没有像 shm_open() 这样没有文件名的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55704758/
这段代码: extern crate libc; use libc::{O_CREAT, O_RDWR, shm_open}; use std::ffi::CString; fn shm_create
我正在像这样创建一个新的共享内存对象 int fd = shm_open("somekey", O_CREAT | O_RDWR, S_IRWXU | S_IRWXG); 返回值很好,我希望在/d
我正在尝试使用 shm_open() 创建一个新的共享内存文件,但我得到错误号 2(没有这样的文件或目录)。 shm_open ("/DIAG_public", O_CREAT | O_RDWR, S
我的一个 friend 正在为内存受限的 Linux 系统开发一个库。他提议使用 shm_open 为用户计算机上多个不同程序之间的进程间通信分配多个合理大小 (16MB) 的内存。 出现的问题是,如
我正在尝试打开一个共享内存,它给我没有这样的文件或目录错误。但是我在名称区域中有一个文件和一个目录。 fd_sh = shm_open("/home/angus/c_tutorials/interv
我有两个问题: 在使用 shm_open 时,如何知道我是否打开了一个已经存在的共享内存,我正在使用 O_CREATE | O_RDWR。 我正在使用 shm_open 创建/打开一个具有某个名称的共
通常,共享内存是使用映射到进程地址空间的部分磁盘文件实现的。每当在共享区域上发生内存访问时,文件系统都会参与将更改写入磁盘,这是一个很大的开销。 通常,调用 fopen() 会返回传递给 mmap()
这样做有什么好处:shm_open 跟在 mmap 之后? 为什么不创建一个常规文件,然后将 fd 传递给 mmap? 我看不出 shm_open 的优势 - 这些只是引用,不是吗? 我看过全家的男人
POSIX shm_open() 函数返回可用于访问共享内存的文件描述符。这是非常方便的,因为可以使用所有控制文件描述符的传统机制来控制共享内存。 唯一的缺点是 shm_open() 总是需要一个文件
我正在编写一个使用 POSIX 共享内存的程序,但有一个我不确定如何修复的错误。我寻找了类似的问题,但找不到与此特定问题相关的任何问题。 涉及两个文件 - server.c,其中包含程序运行的代码,以
我得到了以下成功执行的 C 代码: ... fd = shm_open(memory_package_name, O_CREAT | O_RDWR | O_EXCL , S_IRUSR | S_IWU
我有一个公共(public)的共享内存空间,多个进程可以读写它。我在使用 shm_open() 访问共享内存并使用 mmap() 写入内存映射文件时遇到了这个问题。但是,在调用我的包装器方法几次之后,
我有以下结构, typedef struct arrays { int *array; int max; int min; } array; 其中*array指向一个动态分配的
我不想创建一个新的共享内存对象,如果它不退出的话。而是在这种情况下返回错误。如果它已经存在,我只想打开它。 最佳答案 阅读shm_overview(7) & shm_open(3) . 如果 shm_
我目前正在 ubunto 上开发一个应用程序并调用 shm_open,目前默认路径在/var/run/shm 中。但是我需要将其更改为/tmp。简单地尝试以下是行不通的: fd = shm_open(
在 Linux 中,我想与其他进程共享我的进程的一些内存内容。其中一种方法是使用 shm_open 和 mmap。如下所示。 /* Create a new memory object */ fd =
我正在尝试使用我在网上找到的示例和文档来创建共享内存区域。我的目标是 IPC ,所以我可以让不同的进程相互通信。 这是我的 C 文件 #include #include #include #in
我正在使用boost库在C++程序的IPC上工作,并且发现如果我请求的内存大小大于其容量,boost::shared_memory_object不会抛出任何错误。在堆栈溢出中至少已两次询问此问题: W
描述: 我有一个名为“Projet”的项目目录,其中包含两个名为“Serveur”和“Client”的目录。 (1)Serveur包含serveur.c (2)Client包含client.c 引用t
我刚刚阅读了 shm_open 和 shmat 的联机帮助页,并正在尝试以下示例。在文件 test.c 中, int main(int argc, char **argv) { void *ret
我是一名优秀的程序员,十分优秀!