我是C语言和链接技术的初学者,.so共享库有两个问题。
假设我有一个math.so共享库,该共享库最初是由add.c和multiple.c创建的, 而且我有一个程序test.c,仅在add.c中使用添加功能。
Q1-即使我没有使用多重函数,整个math.so共享库(包括多重代码和数据)仍将加载到内存中,我的理解正确吗?
Q2-由于math.so在内存中共享,因此我们如何处理math.so中的全局数据?例如在add.c中有一个全局变量number = 0,test.c通过number = 1
对其进行了修改,另一个程序test2.c通过number = 2对其进行了修改,因此在上下文切换之后,test.c尝试打印出number的值为2,而不是应该用于test.c的值(应该为1)?
答案 0 :(得分:1)
即使我没有使用多重功能,整个math.so共享库(包括多重代码和数据)仍将加载到内存中
不太正确。
整个库将mmap
加入到您的进程中。但是,大多数现代操作系统都使用demand paging,这意味着直到被访问时,代码和数据才被实际上加载到内存中。
如果共享库很大(大于一页,通常为4KiB或8KiB),并且只能访问该库中的一个函数,则很有可能库中未使用的部分实际上不是加载到内存中。
由于math.so在内存中共享,因此我们如何处理math.so中的全局数据?
全局数据也以copy on write语义mmap
进入您的流程。
如果您有两个进程,并且每个读取 number
的值,该值是math.so
中的全局变量,则两个进程将使用(共享)相同的实际物理页的RAM。但是只要其中一个进程将写入number
,就会为该进程分配一个新的RAM物理页(取消共享该页),并且仅对(现在是私人)副本。