Why use shm_open?
Asked Answered
D

4

34

What's the advantage of doing: shm_open followed a mmap?
Why not create a regular file, and then pass that fd to mmap?
I can't see the advantage of shm_open - these are just references, are they not?

I've read the man of the whole family. It seems to me, that the "secret" is in the mmaping action - the file "type" seems to be meaningless.

Any pointers will be good, especially with performance account.
My context is a (cyclic over-writable) buffer (say 128MB) that will be constantly written to be one process, and constantly dumped from by another.

As an example: what's wrong with this open/mmap approach.

EDIT
To be precise, is one of the following better than the other:

fd = open("/dev/shm/myshm.file", O_CREAT|O_RDWR, S_IRUSR | S_IWUSR);
mem = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

vs.

fd = shm_open("/myshm.file", O_RDWR|O_CREATE, S_IRUSR | S_IWUSR);
mem = mmap(...same as before...);

When I created a file with regular open under the /dev/shm fs, and dumped a Gig of garbage to it, my available memory went down by 1G, and my avaiable disk space remained the same.
What's the difference between the two methods?

Drayman answered 21/7, 2014 at 21:36 Comment(1)
Just try it. writing to a file is maybe a hundred times slower.Rexferd
R
35

If you open and mmap() a regular file, data will end up in that file.

If you just need to share a memory region, without the need to persist the data, which incurs extra I/O overhead, use shm_open().

Such a memory region would also allow you to store other kinds of objects such as mutexes or semaphores, which you can't store in a mmap()'ed regular file on most systems.

Regress answered 21/7, 2014 at 22:11 Comment(9)
But what if I created the file under the /dev/shm fs? like so, open("/dev/shm/myshm", "w")? What's the advantage of using the shm_open?Drayman
Then it would be pretty much the same if you use shm_open or open, but just remember that's linux specific. It would be rather pontless to do when a standard approach exists. shm_open takes care to locate /dev/shm if it's mounted at a non-standard location too.Regress
Thanks for pointing out the portability issue. Our product ships as a VM to clients, so we control the distribution our code runs over, so we can manage that. What got me on the in first place was the inablity to create logical directories under the /dev/shm fs. This is an artifact of glibc's shm_open, and is not an issue of the fs - so I'm going with open().Drayman
@Trevor, note that according to the POSIX standard: "The interpretation of slash characters other than the leading slash character in name is implementation-defined." Why not stick to using the standard API call and simply work around its limitations, e.g. by using underscore or other special character in the file name to separate the logical parts instead of creating directories under /dev/shm?Soto
What you're suggesting is indeed correct - and I still consider it. However, for example, if I'ld want to perform and inotify on the "our" directory under /dev/shm, I have to resort to perform inotify over /dev/shm - and be exposed to other processes registering in this space. Just one example that comes to mindDrayman
@nos, May shm_open followed by mmap allow you to store a pthread mutex_t which can be modified by the pthread_mutexattr_setpshared function in Ubuntu Linux 15.10 glibc 2.21? The reason for this question is I would like to use pthread_mutex_t to setup interprocess synchronization. Thank you.Isomorphism
@Hristo Iliev and Trevor, May shm_open followed by mmap allow you to store a pthread mutex_t which can be modified by the pthread_mutexattr_setpshared function in Ubuntu Linux 15.10 glibc 2.21? The reason for this question is I would like to use pthread_mutex_t to setup interprocess synchronization. Thank youIsomorphism
@Frank, Yes you can do that.Regress
@nos, Thank you for your reply. Could you please take a look at the UNIX diff output of glibc 2.21 and glibc 2.22 of pthread_mutexattr_setpshared.c shown in fossies.org/diffs/glibc/2.21_vs_2.22/nptl/… and explain why I can still use the pthread_mutexattr_setpshared.c function in Ubuntu Linux 15.10 glibc 2.21 to setup pthread_mutex_t to do interprocess synchronization. I was told , perhaps iincorrectly, that there is a bug in pthread_mutexattr_setpshared.c function in Ubuntu Linux 15.10 glibc 2.21. Thank you.Isomorphism
S
8

After reading the source of shm_open, I can say those two methods are almost the same.

link: https://code.woboq.org/userspace/glibc/sysdeps/posix/shm_open.c.html

shm_open just adds shm_dir prefix then invokes normal open syscall, nothing special.

Stagestruck answered 8/12, 2020 at 5:20 Comment(1)
Crucial difference: the shm_dir prefix typically points to a mount point of a temporary file system, such as tmpfs.Proparoxytone
B
3

Both calls are essentially equivalent on modern Linux - 1st approach could be used to access POSIX shared memory from languages like go (see https://github.com/fabiokung/shm/blob/master/shm_linux.go) where POSIX shared memory not natively available - it might be different for other OS/version where 1st call would lead to some file creation or /dev/shm just not available and/or possibly slower performance. Rules of path merging might also be evolving from version to version of librt

1st approach called memory mapped files API (supported in std libs)

2nd called POSIX shared memory API (requires librt aka libposix on Linux as dependence It's internally constructs path and calls open)

Battaglia answered 30/3, 2017 at 14:1 Comment(0)
R
0

It's true that mmap(fopen(/dev/shm)) and shm_open are identical on linux.

They're different on mac simply because /dev/shm doesn't exist on mac!

On mac you could try doing mmap(fopen(some_other_dir)), but then you'd get into struggles to figure out whether some_other_dir will also be on a RAM-backed filesystem, hence whether it will be as performance as shm_open.

Rhines answered 31/3, 2022 at 21:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.