file - mmap 文件不同步
问题描述
您好,我正在尝试通过 mmap 备份矢量。但是,我尝试过 msync 然后 munmap 但它不起作用。在我写入 (char *) 然后 munmap 文件后,该文件没有内容。mmap 文件也是使用标志 MAP_SHARED 创建的。如果有人可以提供帮助,我将不胜感激。
//update file descriptor
if ((fd = open(filename.c_str(), O_RDWR | S_IRWXU)) < 0) { //| O_CREAT
printf("ERROR opening file %s for writing", filename.c_str());
exit(1);
}
//lseek create a file large enough
off_t i = lseek(fd, frontier_size * URL_MAX_SIZE, SEEK_SET);
if (i != frontier_size * URL_MAX_SIZE) {
cout << "failed to seek";
}
//reposition and write 3 bytes to the file else will failed to read
char buff[3] = "ta";
ssize_t kk = lseek(fd, 0, SEEK_SET);
if (kk < 0) {
cout << "failed to reposition";
}
ssize_t temp_write = write(fd, (void *)& buff, 2);
if (temp_write < 0) {
cout << "failed to write";
cout << temp_write;
}
//reposition to begining
ssize_t k = lseek(fd, 0, SEEK_SET);
if (k < 0) {
cout << "failed to reposition";
}
char * map = (char *)mmap(0, frontier_size * URL_MAX_SIZE, PROT_WRITE, MAP_SHARED, fd, 0);
if (map == MAP_FAILED) {
printf("failed mmap");
exit(1);
}
mmap_frontier = map;
//write to frontier
for (int i = 0; i < frontier.size(); ++i) {
strcpy(mmap_frontier, frontier[i].c_str());
mmap_frontier += URL_MAX_SIZE;
}
mmap_frontier -= frontier.size() * URL_MAX_SIZE;
ssize_t k = lseek(fd, 0, SEEK_SET);
if (k < 0) {
cout << "failed to reposition";
}
int sync = msync((void *)0, frontier.size() * URL_MAX_SIZE, MS_ASYNC);
if (sync < 0 ) {
cout << "failed to sync";
}
int unmap = munmap((void *)0, frontier.size() * URL_MAX_SIZE);
if (unmap < 0) {
cout << "failed to unmap";
}
解决方案
您的代码和问题存在很多问题:
S_IRWXU
是 的第三个参数open()
,而不是第二个参数的标志。mmap()
如果文件太小,将无法正常工作。您可以使用ftruncte()
正确设置文件大小。您尝试查找映射的总大小并写入几个字节 ("ta"
),但在此之前您发出了查找lseek(fd, 0, SEEK_SET)
,这意味着文件大小设置为 3 而不是 mapping_size+3。- 您没有使用 mmapped 文件支持矢量,矢量与它无关,矢量使用与此映射没有任何关系的自己的内存(请编辑您的问题...)。
msync()
您使用地址调用(void *)0
,因此需要同步的实际地址 ,map
没有被同步。- 同样,您
munmap()
使用 address 进行了调用(void *)0
,因此需要取消映射的实际地址并未取消映射。 - 您调用
msync()
了 withMS_ASYNC
,这意味着在您读取文件内容之前无法保证同步发生。
这对我有用(为简洁起见,省略了错误处理):
unsigned frontier_size = 2;
const unsigned URL_MAX_SIZE = 100;
int fd = open("data", O_RDWR);
loff_t size = frontier_size * URL_MAX_SIZE;
ftruncate(fd, size);
char *map = (char *)mmap(0, size, PROT_WRITE, MAP_SHARED, fd, 0);
strcpy(map, "hello there");
msync(map, size, MS_SYNC);
munmap(map, size);
close(fd);