mmap学习

rocksdb的WAL文件的具体的实现方式是linux的mmap,如果要主备同步的话,就需要在另一个进程里面读取这个文件,下面记录一下另一个进程查看mmap(MAP_SHARED)的文件的情况。

写的实验代码:

#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    int fd = open("text.txt", O_CREAT | O_RDWR | O_TRUNC, 0644);
    printf("before fallocate\n");
    char c = getchar();
    int iret = fallocate(fd, 0, 0, 1 << 15);
    if (iret != 0) {
        printf("fallocate error %d\n", iret);
        return 1;
    }
    printf("before mmap\n");
    c = getchar();
    void *ptr = mmap(NULL, 1 << 15, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (ptr == MAP_FAILED) {
        printf("mmap failed\n");
        return 1;
    }
    printf("before write\n");
    c = getchar();
    char *tptr = (char *)ptr;
    tptr[0] = 'a';
    tptr[1] = 'b';
    printf("before sync\n");
    close(fd);
    c = getchar();
    printf("test end\n");
}

这个测试的关键是tptr[0] = 'a'这行运行后,到close之前,另一个进程能不能读到这个内容。

读的实验代码

 1 #include<stdio.h>
 2 #include<unistd.h>
 3 
 4 int main() {
 5     FILE *fp = fopen("text.txt", "rb");
 6     char buf[10];
 7     while (1) {
 8         size_t ret = read(fileno(fp), buf, 1);
 9         if (ret <= 0) {
10             printf("fread ret 0\n");
11             break;
12         }
13         buf[1] = '\0';
14         printf("buf %s", buf);
15         getchar();
16         fseek(fp, 0L, SEEK_SET);
17     }
18     fclose(fp);
19 }

上面的读能读到写进程的文字,但是将上面的read改为fread,就会发现程序读不到数据了。这是因为fread有自己进程内的buf,另一个进程的数据肯定不会同步过来,而read用的系统的page cache,是进程间共享的。

原文地址:https://www.cnblogs.com/jfwang/p/4448215.html