文件映射是一种将磁盘上的文件映射到进程的虚拟内存空间的机制。
通过这种方式,进程可以直接通过内存地址来读写文件,而不必通过常规的 read 和 write 等系统调用。
在文件映射中,我们通过Linux的机制将文件和进程的虚拟内存联系起来,使得进程可以直接在内存中读写文件数据,而无需直接访问磁盘。这种机制提供了更高效的文件访问方式,同时也简化了文件操作的流程。
文件映射通常被称为内存映射,这两者通常是一样的,内存映射涵盖了将文件映射到内存和将匿名内存映射到进程地址空间的操作。
文件映射是内存映射的一种特例。
查看对应进程的文件映射信息
$ pmap -X 12345#查看指定PID的文件映射信息 12345: ./example 0000555555554000100K r-x-- example 00005555556730004K r---- example 00005555556740004K rw--- example 00007ffff7de0000 1360K r-x-- libc-2.31.so ... mapped: 1448Kwriteable/private: 8Kshared: 0K
使用 cat /proc/PID/maps
命令可以查看进程的内存映射情况。
每一行都表示一个内存映射区域,格式如下:
address perms offsetdev inodepathname 00400000-0040b000 r-xp 00000000 08:01 1167685/usr/bin/cat 0060a000-0060b000 r--p 0000a000 08:01 1167685/usr/bin/cat 0060b000-0060c000 rw-p 0000b000 08:01 1167685/usr/bin/cat
现在我们通过一个例子演示了如何使用文件映射将文件映射到内存中,然后通过修改内存中的内容,最后通过解除内存映射来进行演示。
example.c文件
#include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main() { const char *file_path = "example.txt"; const size_t file_size = 4096; int fd = open(file_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } if (ftruncate(fd, file_size) == -1) { perror("ftruncate"); close(fd); exit(EXIT_FAILURE); } // Create a memory-mapped region void *addr = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (addr == MAP_FAILED) { perror("mmap"); close(fd); exit(EXIT_FAILURE); } // Now 'addr' points to the beginning of the file in memory // 现在addr表示文件在进程的内存空间代表区域的起始位置 // Write a message to the memory-mapped file // 向映射文件写入一句消息。 const char *message = "Hello, Memory Mapping!n"; strncpy(addr, message, strlen(message)); printf("Press Enter to exit...n"); getchar();// Wait for user to press Enter // Unmap the memory region解除文件和内存区域的映射关系 if (munmap(addr, file_size) == -1) { perror("munmap"); close(fd); exit(EXIT_FAILURE); } // Close the file descriptor close(fd); return 0; }
编译执行:
$ ls example.c $ gcc example.c -o example $ ./example Press Enter to exit...
查看进程的文件映射信息:
$ ps aux|grep example codersong 15245420.00.0 27761152 pts/0S+ 19:23 0:00 ./example codersong 15245470.00.0121882432 pts/2S+ 19:23 0:00 grep --color=auto example $ pmap -X 1524542 1524542: ./example 地址 Perm 偏移量 设备 Inode SizeRss Pss Pss_Dirty Referenced Anonymous LazyFree ShmemPmdMapped FilePmdMapped Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked THPeligible Mapping 557b482c3000 r--p0000000008:03 712405144 4 04 000 00 00 00 0 example 557b482c4000 r-xp0000100008:03 712405144 4 04 000 00 00 00 0 example 557b482c5000 r--p0000200008:03 712405144 4 04 000 00 00 00 0 example 557b482c6000 r--p0000200008:03 712405144 4 44 400 00 00 00 0 example 557b482c7000 rw-p0000300008:03 712405144 4 44 400 00 00 00 0 example 557b48e9e000 rw-p0000000000:00 01324 4 44 400 00 00 00 0 [heap] 7f8fe5600000 r--p0000000008:03264612160160 7 0160 000 00 00 00 0 libc.so.6 7f8fe5628000 r-xp0002800008:03264612 162078824 0788 000 00 00 00 0 libc.so.6 7f8fe57bd000 r--p001bd00008:03264612352 64 1 0 64 000 00 00 00 0 libc.so.6 7f8fe5815000 r--p0021400008:03264612 16 161616 161600 00 00 00 0 libc.so.6 7f8fe5819000 rw-p0021800008:0326461288 8 88 800 00 00 00 0 libc.so.6 7f8fe581b000 rw-p0000000000:00 0 52 202020 202000 00 00 00 0 7f8fe58f6000 rw-p0000000000:00 0 128 8 88 800 00 00 00 0 7f8fe5908000 rw-p0000000000:00 084 4 44 400 00 00 00 0 7f8fe590a000 r--p0000000008:0326460088 0 08 000 00 00 00 0 ld-linux-x86-64.so.2 7f8fe590c000 r-xp0000200008:03264600168168 7 0168 000 00 00 00 0 ld-linux-x86-64.so.2 7f8fe5936000 r--p0002c00008:03264600 44 40 1 0 40 000 00 00 00 0 ld-linux-x86-64.so.2 7f8fe5941000 rw-s0000000008:03 712405244 4 04 000 00 00 00 0 example.txt 7f8fe5942000 r--p0003700008:0326460088 8 88 800 00 00 00 0 ld-linux-x86-64.so.2 7f8fe5944000 rw-p0003900008:0326460088 8 88 800 00 00 00 0 ld-linux-x86-64.so.2 7ffef93f2000 rw-p0000000000:00 0132 121212 121200 00 00 00 0 [stack] 7ffef9485000 r--p0000000000:00 0 160 0 00 000 00 00 00 0 [vvar] 7ffef9489000 r-xp0000000000:00 084 0 04 000 00 00 00 0 [vdso] ffffffffff600000 --xp0000000000:00 040 0 00 000 00 00 00 0 [vsyscall] ==== ==== === ========= ========== ========= ======== ============== ============= ============== =============== ==== ======= ====== =========== 2780 1344 15296 13449600 00 00 00 0 KB $ $ $ cat /proc/1524542/maps 557b482c3000-557b482c4000 r--p 00000000 08:03 7124051/home/codersong/zhengshihong/example 557b482c4000-557b482c5000 r-xp 00001000 08:03 7124051/home/codersong/zhengshihong/example 557b482c5000-557b482c6000 r--p 00002000 08:03 7124051/home/codersong/zhengshihong/example 557b482c6000-557b482c7000 r--p 00002000 08:03 7124051/home/codersong/zhengshihong/example 557b482c7000-557b482c8000 rw-p 00003000 08:03 7124051/home/codersong/zhengshihong/example 557b48e9e000-557b48ebf000 rw-p 00000000 00:00 0[heap] 7f8fe5600000-7f8fe5628000 r--p 00000000 08:03 264612 /usr/lib/x86_64-linux-gnu/libc.so.6 7f8fe5628000-7f8fe57bd000 r-xp 00028000 08:03 264612 /usr/lib/x86_64-linux-gnu/libc.so.6 7f8fe57bd000-7f8fe5815000 r--p 001bd000 08:03 264612 /usr/lib/x86_64-linux-gnu/libc.so.6 7f8fe5815000-7f8fe5819000 r--p 00214000 08:03 264612 /usr/lib/x86_64-linux-gnu/libc.so.6 7f8fe5819000-7f8fe581b000 rw-p 00218000 08:03 264612 /usr/lib/x86_64-linux-gnu/libc.so.6 7f8fe581b000-7f8fe5828000 rw-p 00000000 00:00 0 7f8fe58f6000-7f8fe58f9000 rw-p 00000000 00:00 0 7f8fe5908000-7f8fe590a000 rw-p 00000000 00:00 0 7f8fe590a000-7f8fe590c000 r--p 00000000 08:03 264600 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7f8fe590c000-7f8fe5936000 r-xp 00002000 08:03 264600 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7f8fe5936000-7f8fe5941000 r--p 0002c000 08:03 264600 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7f8fe5941000-7f8fe5942000 rw-s 00000000 08:03 7124052/home/byzoro/zhengshihong/example.txt 7f8fe5942000-7f8fe5944000 r--p 00037000 08:03 264600 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7f8fe5944000-7f8fe5946000 rw-p 00039000 08:03 264600 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 7ffef93f2000-7ffef9413000 rw-p 00000000 00:00 0[stack] 7ffef9485000-7ffef9489000 r--p 00000000 00:00 0[vvar] 7ffef9489000-7ffef948b000 r-xp 00000000 00:00 0[vdso] ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0[vsyscall]
现在按ctrl+C
退出example程序,查看example.txt文件的内容:
$ cat example.txt Hello, Memory Mapping!
以上是Linux文件映射的查看方法有哪些的详细内容。更多信息请关注PHP中文网其他相关文章!