我有一个在内存中生成大量数据的C程序,我需要在内存中共享这些数据的一个特定部分,以便另一个进程可以对它进行读取访问.
我试图mmap这样做,但我没有取得多大成功.这是我的代码:
//Code above generates a pointer to the memory section I need to share, named addr
if (infoBlock->memory_size == 1073741824) { //This is the data block I need to share
int err, fd;
fd = open("/tmp/testOutput", (0_RDWR | 0_CREAT), S_IWUSR);
if (fd < 0) {
perror("Couldn't create output file\n");
goto failedExit;
}
unsigned *p = mmap(addr, 1073741824, PROT_READ, (MAP_SHARED | MAP_FIXED), fd, 0);
if (!p) {perror("mmap failed"); goto failedExit; }
printf("p is now: %p\n", p); //This should point to the shared mapping
printf("%u\n", *p); //Try to print out some data from the mapping
}
Run Code Online (Sandbox Code Playgroud)
运行程序后,我可以看到文件/ tmp/testOutput存在,但它的大小是0.我不确定这是否是内存映射的正常事情,因为它在技术上不是一个文件.此程序中的所有输出也指向相同的内存地址.
我还可以看到/ proc/PID/maps中存在的内存映射,并引用了/ tmp/testOutput.
一切似乎都在运行,但是当它取消引用指针时,程序退出,我假设这是因为我完成了映射错误,并且指针指向它不应该的东西.
如果有人能够发现我做错了什么,或者可以提供一些建议,我们将不胜感激.
谢谢!
您已将与该文件关联的存储(或尝试)存储到您的进程中,并且您已坚持将其映射到您已用于其他内容的地址(可能addr是以某种方式分配).
您没有说p实际上是否确实拥有您请求的地址,并且正如嫌疑人指出的那样,您的错误检查已被破坏.
事后,您无法将任意堆或其他进程内存页与文件关联.您必须在文件系统中分配它们,然后映射它们.(有一种方法可以使用vmsplice将它们与UNIX管道相关联,尽管它并不完全符合您的要求).
请注意,该MMAP_FIXED标志将仅替换您的数据占用的页面,以及与该文件关联的新页面.如果没有该标志,则会忽略地址提示,并将映射放在其他位置.
mmap错误检查如果您无法更改分配方案,那么您可以管理的最佳方法是将流程本地内存复制到映射中,在这种情况下,您可以将write其更改为文件.
理想的情况看起来像这样:
void *alloc_mmap(const char *filename, size_t length)
{
int fd;
fd = open(filename, (0_RDWR | 0_CREAT), S_IWUSR);
if (fd < 0) {
perror("Couldn't create output file\n");
return NULL;
}
if (ftruncate(fd, length)) {
perror("Couldn't grow output file\n");
close(fd);
return NULL;
}
void *p = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
if (p == -1) {
perror("mmap failed");
close(fd);
return NULL;
}
close(fd);
return p;
}
// now you've allocated your memory, you can populate it and it will be
// reflected in the file
Run Code Online (Sandbox Code Playgroud)