当我想在linux中映射一些共享内存时,我会这样做:
hFileMap = open(MapName, O_RDWR | O_CREAT, 438);
pData = mmap(NULL, Size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, hFileMap, 0);
它工作得很好。它正确映射内存。然而,有三件事我不喜欢。
它会在光盘上创建一个物理文件。我必须手动删除此文件或使用remove
功能。我喜欢在Windows上没有物理文件,除非我自己物理地映射文件。我想在linux上做同样的事情。
我必须使用ftruncate
来设置文件的长度。否则,memcpy
会在将数据复制到文件时出现段错误。我的意思是,当我必须首先指定mmap的大小时,文件有0个空间没有多大意义..
尺寸固定。我不需要调整大小,因此不需要ftruncate
?
在没有物理文件的情况下,是否仍然可以映射内存并且还有其他进程可以访问它?解决方案的缺点是什么?
我并不太关心ftruncate
,但有没有办法取消通话?当我不在Windows上时,我只是困扰我一点点我必须这样做。
答案 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是你最好的选择。