mmap文件未同步

问题描述 投票:0回答:1

您好,我正在尝试通过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";
    }
file filesystems mmap lseek
1个回答
0
投票

您的代码和问题有很多问题:

  • [S_IRWXUopen()的第三个参数,不是第二个参数的标志。
  • mmap()如果文件太小,将无法正常工作。您可以使用ftruncte()正确设置文件大小。您试图超越映射的总大小并写入几个字节("ta"),但在此之前,您发出了寻求lseek(fd, 0, SEEK_SET),这意味着文件大小设置为3,而不是mapping_size + 3。] >
  • 您没有用一个映射文件来支持该向量,该向量与它无关,该向量使用了自己的内存,该内存与该映射没有任何关系(请编辑您的问题...)。
  • 您用地址msync()呼叫了(void *)0,因此未同步需要同步的实际地址map
  • 同样,您使用地址munmap()调用了(void *)0,因此未取消映射需要取消映射的实际地址。
  • 您用msync()调用了MS_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);
© www.soinside.com 2019 - 2024. All rights reserved.