我有一个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
}
运行程序后,我可以看到文件/ tmp / testOutput存在,但是它的大小是0.我不确定这是否是内存映射的正常事情,因为它在技术上不是文件。此程序中的所有输出都指向相同的内存地址。
我还可以看到/ proc / PID / maps中存在的内存映射,并引用了/ tmp / testOutput。
所有东西似乎都在运行,但是当取消引用指针时,程序退出,我假设这是因为我完成了映射错误,并且指针指向它不应该的东西。 / p>
如果有人能够发现我做错了什么,或者可以提供一些建议,我们将不胜感激。
谢谢!
答案 0 :(得分:5)
您已将与该文件相关联(或已尝试过)的存储映射到您的流程中,并且您已坚持将其映射到您已用于其他内容的地址(可能是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
答案 1 :(得分:1)
以下是mmap手册页的摘录。
On success, mmap() returns a pointer to the mapped area. On error, the value
MAP_FAILED (that is, (void *) -1) is returned, and errno is set appropriately.
On success, munmap() returns 0, on failure -1, and errno is set (probably to
EINVAL).
应该将成功测试更改为测试mmap的-1返回值。然后检查错误 值。 HTH。