没有ftruncate的Linux上的共享内存物理文件?

时间:2014-08-07 01:29:53

标签: c++ c linux

当我想在linux中映射一些共享内存时,我会这样做:

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

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

它工作得很好。它正确映射内存。然而,有三件事我不喜欢。

  1. 它会在光盘上创建一个物理文件。我必须手动删除此文件或使用remove功能。我喜欢在Windows上没有物理文件,除非我自己物理地映射文件。我想在linux上做同样的事情。

  2. 我必须使用ftruncate来设置文件的长度。否则,memcpy会在将数据复制到文件时出现段错误。我的意思是,当我必须首先指定mmap的大小时,文件有0个空间没有多大意义..

  3. 尺寸固定。我不需要调整大小,因此不需要ftruncate

  4. 在没有物理文件的情况下,是否仍然可以映射内存并且还有其他进程可以访问它?解决方案的缺点是什么?

    我并不太关心ftruncate,但有没有办法取消通话?当我不在Windows上时,我只是困扰我一点点我必须这样做。

2 个答案:

答案 0 :(得分:2)

您可以使用shm_open创建共享内存区域。以下代码段演示了如何使用shm_open()创建共享内存对象,然后使用ftruncate()在使用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用于设置文件的大小。因此,如果您不想调用它,可以手动写入0个字节来填充文件。

答案 1 :(得分:1)

shm_open仍将在文件系统中创建一个文件来表示共享内存对象。

您可以使用map_anonymous和map_shared调用mmap,它不会创建任何文件。但是,其他进程必须是当前进程的子进程,并且必须在调用fork之前设置mmap。

如果这不起作用,那么shm_open是你最好的选择。