如何更改shm_open路径?

4

我目前正在Ubuntu上开发一个应用程序,并调用shm_open函数。默认路径在/var/run/shm下,但我需要将其更改为/tmp。尝试以下方法无效:

fd = shm_open("/tmp/test", O_RDWR | O_CREAT, 0777);

请问有什么建议吗?


抱歉,我的错误。当我删除 /tmp 后,它返回 3。但是执行上述命令时返回 -1。 - godzilla
当您在shm_open返回-1后调用perror(NULL);会发生什么? - Jason
问题在于没有像/dev/shm/tmp/这样的目录...因此,您无法创建名为/dev/shm/tmp/test的文件,因为不存在tmp目录。如果必须使用/tmp,则@Mihai的答案是正确的,否则您可以简单地使用test,这将创建/dev/shm/test - Jason
这里有另一个链接可以尝试:http://fixunix.com/sgi/112129-linux-shm_open-bad-file-descriptor-sgi-runs-well.html - Jason
2
这不是共享内存对象的工作方式...在Linux上,默认情况下它们是在/dev/shm中创建的,如果您想将它们放在其他地方,您必须在所需目录中挂载一个tmpfs文件系统。 - Jason
显示剩余8条评论
2个回答

12

根据shm_open(3)的手册页面:

name参数用于创建或打开一个指定的共享内存对象。为了便于移植,共享内存对象应该使用形如/somename的名称标识;也就是说,一个由斜杠开始、后面跟着一个或多个字符的、不超过NAME_MAX(即255)个字符的空结束字符串,该字符串中不能包含斜杠

shm_open(3)函数的name参数是一个对象名,而非文件路径!只是碰巧GLIBC通过在对象名前添加路径并调用open()函数,将所有共享内存对象放置在/dev/shm/var/run/shm下。如果你将/tmp/test作为共享对象名,Linux会尝试打开或创建/var/run/shm/tmp/test。通过带有O_CREAT标志的open()可以创建新文件,但无法创建新目录

如果您在调用shm_open("/tmp/test", ...)之前先创建目录/var/run/shm/tmp,那么您的测试将会成功。请记得在使用共享内存对象后删除该目录。同时请注意,使用两个斜杠的对象名可能在其他Unix系统上无法移植。


我在哪里可以设置目标路径,例如:/dev/shm - DDS
@DDS 你不能这样做。在Linux上,它会搜索一个tmpfs挂载点,通常挂载在/dev/shm/var/run/shm下面。 - Hristo Iliev
在我的情况下,/var/volatile和/run都是tempfs,并且我的布局如下:/tmp -> /var/tmp -> /var/volatile/tmp。 - DDS

2
您需要在/tmp目录下挂载一个tmpfs文件系统来完成此操作:
mihai@keldon:~$ mount | grep shm
shm on /dev/shm type tmpfs (rw,nosuid,nodev,relatime)

否则不可能。

我尝试了 mount | grep shm 但是得到了以下结果 none on /run/shm type tmpfs (rw,nosuid,nodev)。 - godzilla
不好意思,上面只显示了文件系统的类型,你需要使用mount命令进行挂载。 - Mihai Maruseac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接