当前位置:网站首页>C专家编程 第5章 对链接的思考 5.2 动态链接的优点
C专家编程 第5章 对链接的思考 5.2 动态链接的优点
2022-08-04 04:44:00 【weixin_客子光阴】
动态链接的优点:
可执行文件体积小;
虽然运行速度稍慢一些,但动态链接能更加有效地利用磁盘空间,而且链接-编辑的时间也会缩短
(因为链接器的有些工作被推迟到载入时)
动态链接的目的之一是ABI
动态链接的主要目的就是把程序与它们使用的特定的函数库版本中分离开来。取而代之的是,我们约定由系统向程序提供一个接口,该接口保持稳定,不随时间和操作系统的后续版本发生变化。
接口是介于应用程序和函数库二进制可执行文件所提供的服务之间的接口,所以称它为应用二进制
接口(Application Binary Interface, ABI)
将基于AT&T的SVr4的UNIX世界进行统一的目的就是提供一个单独的ABI。ABI保证函数库存在于所有遵循约定的机器中,并保证接口的完整性。动态链接必须保证4个特定的函数库:libc(C运行时函数库)、libsys(其他系统函数) 、libX(X windowing)和libnsl(网络服务)。其他的函数可以通过静态链接,但最好采用动态链接。
动态链接单个可执行文件的启动速度稍受影响,但动态链接可以从以下方面提高性能。
1.动态链接可执行文件比功能相同的静态链接可执行文件的体积小。它能够节省磁盘空间和虚拟内存,因为函数库只有在需要时才被映射到进程中。
2.所有动态链接到某个特定函数库的可执行文件在运行时共享该函数库的一个单独副本。操作系统内核保证映射到内存中的函数可以被所有使用它们的进程共享。
动态链接使得函数库的版本升级更为容易。新的函数库可以随时发布。
最后(虽然并不常见,但仍可能出现)动态链接允许用户在运行时选择需要执行的函数库。这就使为了提高速度或者提高内存使用效率或包含额外的调试信息而创建新版本的函数库是完全有可能的。
动态链接是一种“just-in-time(JIT)”链接,这意味着程序在运行时必须能够找到他们需要的函数库。链接器通过把库文件名和路径名植入可执行文件中来做到这一点。这意味着,函数库的路径不能随意移动。除非在链接器中进行特别说明。否则,当程序员调用该函数库的函数时,就会在运行时导致失败,并给出这样一条错误信息。
ld.so.1: main: fatal: libthread.so: can't open file: errno = 2
任何人都可以创建静态或动态的函数库。只需要简单地编译一些不包含main函数的代码,并把编译所生的.o文件用正确的实用工具进行处理:如果是静态库,则使用ar; 如果是动态库,则使用ld。
系统调用mmap()把文件映射到进程的地址空间中。
所有的应用程序只使用动态链接。使用静态链接的最大危险在于未来版本的操作系统可能与可执行文件所绑定的系统函数库并不兼容。而且有些函数库(如libaio.so, libsys.so, libsolv.so以及librpcsvs.so等)只能以动态链接的形式使用。
静态库被称作archive, 它们通过ar(用于archive的使用工具)来创建和更新。静态库约定在他们的文件名中使用“.a”作为扩展名。
在SVr3中,还存在一种中间性质的链接,介于静态链接和动态链接之间,成为“静态共享库”(static shared libraries)。在生命期内,它们的地址始终固定,这样它们就可以直接绑定到应用程序中,较之动态链接少了一层中间环节。另外,它们显得不是很灵活,而且需要操作系统提供很多支持。
动态链接由链接编辑器ld创建。根据约定,动态库的文件扩展名为“.so”,表示“shared object”(共享对象)--- 每一个链接到该函数库的程序共享它的同一份副本。
/*动态链接库的最简单形式可以通过在cc命令上加上-G选项来创建,如下所示:*/
%cat tomato.c
my_lib_function() {
printf("library routine called\n");
}
//-G来创建动态链接
%cc -o libfruit.so -G tomato.c
/*然后可以利用这个动态链接库来编写程序,并且使用下面这种方法与函数库进行链接*/
%cat test.c
int main() {
my_lib_function();
}
//-L/home/linden 链接时是从那个目录寻找需要链接的函数库
//-R/home/linden 运行时是从那个目录寻找需要链接的函数库
%cc test.c -L/home/linden -R/home/linden -lfruit
%a.out
编译器选项-K pic来为函数库产生与位置无关的代码。与位置无关的代码表示用这种方法产生的代码保证对于任何全局数据的访问都是通过额外的间接方法来完成的。这使他很容易对数据进行重新定位,只要简单地修改全局偏移量表中的其中一个值就可以了。
类似地,每个函数调用的产生就像是通过过程链接表的某个间接地址所产生的一样。这样,文本
可以很容易地重新定位到任何地方,只要修改一下偏移量表就可以了。所以当代码在运行时被映射
进来时,运行时链接器可以直接把他们放在任何空闲的地方,而代码本身并不需要修改。
在缺省情况下,编译器并不产生与位置无关的代码,因为额外的指针解引用操作将使程序在运行时稍稍变慢。然而,如果不使用与位置无关的代码,则所产生的代码就会被对应到固定的地址,这对于可执行文件来说确实很好,但对于共享库,速度却要慢一点,因为现在每个全局引用就不得不在运行时通过修改页面安排到固定的位置, 这就使得页面无法共享。
运行时链接器总能够安排对页面的引用。但是,使用位置无关代码可以极大地简化任务。当然需要权衡一下,位置无关代码与由运行时链接器安排代码相比,速度是快了还是慢了。 根据经验,对于函数库应该始终使用与位置无关的代码。对于共享库,与位置无关的代码显得格外有用,因为每个使用共享库的进程一般都会把它映射到不同的虚拟地址(尽管共享同一份物理副本)
“纯代码(pure code)”,纯可执行文件是只包含代码(无静态或初始化过的数据)的文件。之所以称为“纯”,是因为它不必进行修改就能被其他特定的进程执行。它从堆栈或者其他(非纯)段引用数据。纯代码可以被共享。如果生成与位置无关的代码(意味着共享),你通常也希望它是纯代码。
边栏推荐
- 某母婴小程序加密参数解密
- 备份工具pg_dump的使用《postgres》
- [21 Days Learning Challenge] Image rotation problem (two-dimensional array)
- 七夕节,我用代码制作了表白信封
- 2023年PMP考试会用新版教材吗?回复来了!
- 深度学习21天——准备(环境配置)
- This Thursday evening at 19:00, the fourth live broadcast of knowledge empowerment丨The realization of equipment control of OpenHarmony smart home project
- if,case,for,while
- 系统设计.秒杀系统
- 2022 software test interview questions The latest ByteDance 50 real interview questions, 15k have been won after brushing, with explanation + Q&A
猜你喜欢
随机推荐
小程序 + 电商,玩转新零售
文件系统的简单操作
企业直播风起:目睹聚焦产品,微赞拥抱生态
转:管理是对可能性的热爱,管理者要有闯进未知的勇气
Shell 函数
有趣的 Kotlin 0x0E:DeepRecursiveFunction
SQL query String field less than 10 how to check
2022 software test interview questions The latest ByteDance 50 real interview questions, 15k have been won after brushing, with explanation + Q&A
Deep learning -- CNN clothing image classification, for example, discussed how to evaluate neural network model
文件内容的操作
[21 Days Learning Challenge] Image rotation problem (two-dimensional array)
System design. Seckill system
解决问题遇到的问题
结构体函数练习
【MD5】采用MD5+盐的加密方式完成注册用户和登录账号
数据集类型转换—TFRecords文件
数据治理平台项目总结和分析
day13--postman接口测试
JVM笔记
JVM Notes