为什么共享库(.so 文件)加载为私有?
Why are shared libraries (.so files) loaded as private?
这来自 smaps 文件:
b750d000-b76bc000 r-xp 00000000 08:01 918842 /lib/i386-linux-gnu/libc-2.23.so
我相信 r-xp
中的 p
表示它是作为私有加载的。为什么会这样?如果将每个 .so 文件的副本加载到不同进程的不同内存地址,这不会破坏共享库的目的吗?这种私人加载有什么好处?
p
对应MAP_PRIVATE
。 man mmap
声称:
MAP_PRIVATE
: Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. [...]
只要不进行任何修改,此 VMA 的物理内存页面将由所有进程共享 (它们也与内核缓存共享)。当在给定进程中修改虚拟页面时,该进程将复制(取消共享)该页面(写时复制)。
我们来看看:
$ cat /proc/self/maps
00400000-0040c000 r-xp 00000000 08:11 529223 /bin/cat
0060b000-0060c000 r--p 0000b000 08:11 529223 /bin/cat
0060c000-0060d000 rw-p 0000c000 08:11 529223 /bin/cat
[...]
第一个和第二个 VMA 是只读的。它们(通常)不会被修改,并且(通常)会被所有进程共享。
第三个 VMA (rw-p
) 是可写的,但一个进程中的修改必须对其他进程不可见。此 VMA 包含不同进程不共享的(可变)全局变量。
这来自 smaps 文件:
b750d000-b76bc000 r-xp 00000000 08:01 918842 /lib/i386-linux-gnu/libc-2.23.so
我相信 r-xp
中的 p
表示它是作为私有加载的。为什么会这样?如果将每个 .so 文件的副本加载到不同进程的不同内存地址,这不会破坏共享库的目的吗?这种私人加载有什么好处?
p
对应MAP_PRIVATE
。 man mmap
声称:
MAP_PRIVATE
: Create a private copy-on-write mapping. Updates to the mapping are not visible to other processes mapping the same file, and are not carried through to the underlying file. [...]
只要不进行任何修改,此 VMA 的物理内存页面将由所有进程共享 (它们也与内核缓存共享)。当在给定进程中修改虚拟页面时,该进程将复制(取消共享)该页面(写时复制)。
我们来看看:
$ cat /proc/self/maps 00400000-0040c000 r-xp 00000000 08:11 529223 /bin/cat 0060b000-0060c000 r--p 0000b000 08:11 529223 /bin/cat 0060c000-0060d000 rw-p 0000c000 08:11 529223 /bin/cat [...]
第一个和第二个 VMA 是只读的。它们(通常)不会被修改,并且(通常)会被所有进程共享。
第三个 VMA (
rw-p
) 是可写的,但一个进程中的修改必须对其他进程不可见。此 VMA 包含不同进程不共享的(可变)全局变量。