简体   繁体   中英

Shared Memory on Linux without ftruncate & physical files?

When I want to map some shared memory in linux, I do:

hFileMap = open(MapName, O_RDWR | O_CREAT, 438);

pData = mmap(NULL, Size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, hFileMap, 0);

and it works just fine. It maps the memory properly. However three things arise that I don't like.

  1. It creates a physical file on the disc. I'd have to remove this file manually or using remove function. I like that on Windows there is no physical file unless I map a file physically myself. I'd like to do the same on linux.

  2. I have to use ftruncate to set the length of the file. Otherwise memcpy will segfault when copying data into the file. I mean, it doesn't make much sense for the file to have 0 space when I had to specify the size to mmap in the first place..

  3. The size is fixed. I don't need it resizing so there should be no need for ftruncate ?

Is there anyway at all to map memory without a physical file and still have other processes be able to access it? What would be the disadvantages to a solution?

I don't really care too much about the ftruncate but is there a way to also remove the call? It just bothers me a tiny bit that I have to do this when I don't have to on Windows.

You can use shm_open to create a shared memory region. The following code segment demonstrates the use of shm_open() to create a shared memory object which is then sized using ftruncate() before being mapped into the process address space using mmap():

#include <unistd.h>
#include <sys/mman.h>
...

#define MAX_LEN 10000
struct region {        /* Defines "structure" of shared memory */
    int len;
    char buf[MAX_LEN];
};
struct region *rptr;
int fd;

/* Create shared memory object and set its size */

fd = shm_open("/myregion", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1)
    /* Handle error */;


if (ftruncate(fd, sizeof(struct region)) == -1)
    /* Handle error */;

/* Map shared memory object */

rptr = mmap(NULL, sizeof(struct region),
       PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (rptr == MAP_FAILED)
    /* Handle error */;

/* Now we can refer to mapped region using fields of rptr;
   for example, rptr->len */
...

ftruncate is there to set the size of the file. So if you don't like to call it, you can manually write 0 bytes to fill up the file.

shm_open will still create a file in the file system to represent the shared memory object.

You can call mmap with map_anonymous and map_shared, and it will not create any files. However, the other processes must be children of the current process, and mmap must be setup before fork is called.

If that won't work then shm_open is your best bet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM