gpt4 book ai didi

c - 如何让 mmap 内存同步到文件?

转载 作者:行者123 更新时间:2023-11-30 15:49:53 25 4
gpt4 key购买 nike

我正在为我的 postscript 解释器构建一个内存管理器,我希望它能够挂起磁盘 session 并恢复已保存的 session 。我使用匿名 mmap 设计它,一切似乎都正常。测试代码访问内存似乎没有问题。但现在我已经删除了 MAP_ANONYMOUS 并提供了 O_RDWR 文件描述符,测试运行后我无法看到文件中的内存内容。

#include <stdlib.h> /* exit free malloc realloc */
#include <stdio.h> /* fprintf printf perror */
#include <string.h> /* memset */
#include <unistd.h> /* getpagesize */

#include <sys/stat.h> /* open */
#include <fcntl.h> /* open */

/* placeholder error function */
/* ultimately, this will do a longjmp back to the central loop */
void error(char *msg) {
fprintf(stderr, "%s\n", msg);
perror("last system error:");
exit(EXIT_FAILURE);
}

unsigned pgsz /*= getpagesize()*/; /*=4096 (usually on 32bit)*/

/*
typedef struct {
unsigned char *base;
unsigned used;
unsigned max;
} mfile;
*/

/* dump mfile details to stdout */
void dumpmfile(mfile *mem){
printf("{mfile: base = %p, "
"used = 0x%x (%u), "
"max = 0x%x (%u)}\n",
mem->base,
mem->used, mem->used,
mem->max, mem->max);
unsigned u;
for (u=0; u < mem->used; u++) {
if (u%16 == 0) {
printf("\n%06u %04x: ", u, u);
}
printf("%02x ", (unsigned) mem->base[u]);
}
puts("");
}

/* memfile exists in path */
int getmemfile(){
int fd;
fd = open(
"x.mem",
O_RDWR);
return fd;
}


/* initialize the memory file */
void initmem(mfile *mem){
int fd;
struct stat buf;
size_t sz = pgsz;

fd = getmemfile();
if (fd != -1){
fstat(fd, &buf);
sz = buf.st_size;
if (sz < pgsz) sz = pgsz;
}

#ifdef MMAP
mem->base = mmap(NULL,
sz,
PROT_READ|PROT_WRITE,
MAP_PRIVATE
# ifndef MREMAP
|MAP_AUTOGROW
# endif
| (fd == -1? MAP_ANONYMOUS : 0) , fd, 0);
if (mem->base == MAP_FAILED)
#else
mem->base = malloc(pgsz);
if (mem->base == NULL)
#endif
error("unable to initialize memory file");
mem->used = 0;
mem->max = pgsz;
}

/* destroy the memory file */
void exitmem(mfile *mem){
#ifdef MMAP
munmap(mem->base, mem->max);
#else
free(mem->base);
#endif
mem->base = NULL;
mem->used = 0;
mem->max = 0;
}

// ... omitting some address table functions not relevant here.


mfile mem;

/* initialize everything */
void init(void){
pgsz = getpagesize();
initmem(&mem);
(void)initmtab(&mem); /* create mtab at address zero */
}

void xit(void){
exitmem(&mem);
}

int main(){
init();
unsigned ent;
int seven = 7;
int ret;

//printf("getmemfile: %d\n", getmemfile());

ent = mtalloc(&mem, 0, sizeof seven);
put(&mem, ent, 0, sizeof seven, &seven);
get(&mem, ent, 0, sizeof seven, &ret);
printf("put %d, got %d\n", seven, ret);

unsigned ent2;
ent2 = mtalloc(&mem, 0, 8*sizeof seven);
put(&mem, ent2, 6, sizeof seven, &seven);
get(&mem, ent2, 6, sizeof seven, &ret);
printf("put %d in slot 7, got %d\n", seven, ret);
//get(&mem, ent2, 9, sizeof seven, &ret);
//printf("attempted to retrieve element 10 from an 8-element array, got %d\n", ret);

unsigned ent3;
char str[] = "beads in buddha's necklace";
char sret[sizeof str];
ent3 = mtalloc(&mem, 0, strlen(str)+1);
put(&mem, ent3, 0, sizeof str, str);
get(&mem, ent3, 0, sizeof str, sret);
printf("stored and retrieved %s\n", sret);

xit();
return 0;
}

运行测试,检查文件。

josh@Z1 ~/xpost$ make testcc -g -Wall -Wextra -DTESTMODULE -o m m.c./ob && ./mput 7, got 7put 7 in slot 7, got 7stored and retrieved beads in buddha's necklacejosh@Z1 ~/xpost$ od x.mem0000000 000000 000000 000000 000000 000000 000000 000000 000000*0200000josh@Z1 ~/xpost$

我需要以某种方式冲洗它吗?或关闭文件? 哦。废话,我敢打赌就是这样,不是吗?好吧,我花了一些精力打字,所以我会分享。如果它太本地化,那就这样吧。 不。 close 根本不会改变输出。

更新:现在一切似乎都正常。最后的几个问题是对文件名进行硬编码,在 open() 调用中省略 O_CREAT。以及其他一些小错误。为了更好地衡量,我添加了 msync,但 MAP_SHARED 是上述问题的修复。此模块及相关模块可在 http://code.google.com/p/xpost/source/browse/ 处查看。 .

最佳答案

由于您使用 MAP_PRIVATE 映射内容,因此您对内存区域所做的更改对于您的进程来说是私有(private)的。要使更改对其他任何人可见(写入文件就是这样),您需要使用 MAP_SHARED 进行映射。

此外,您还需要使用ftruncate设置文件的大小。否则,映射区域仅覆盖文件中不存在的部分。

如果您确实想确保数据最终保存在磁盘上,请使用msync,但通常您将能够立即看到写入 mmap:ed 区域的内容,除非您位于少数没有统一缓冲区和对象缓存的操作系统之一。

关于c - 如何让 mmap 内存同步到文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16032396/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com