Linux共享库两种加载方式简述 

动态库技术通常能减少程序的大小,节省空间,提高效率,具有很高的灵活性,对于升级软件版本也更加容易。与静态库不同,动态库里面的函数不是执行程序本身 的一部分,而是在程序执行时按需载入,其执行代码可以同时在多个程序中共享。由于在编译过程中无法知道动态库函数的地址,所以需要在运行期间查找,这对程 序的性能会有影响。

共享库

对于共享库来讲,它只包括2个段:只读的代码段 和可修改的数据段。堆和栈段,只有进程才有。如果你在共享库的函数里,分配了一块内存,这段内存将被算在调用该函数的进程的堆中。代码段由于其内容是对每 个进程都是一样的,所以它在系统中是唯一的,系统只为其分配一块内存,多个进程之间共享。数据段由于其内容对每个进程是不一样的,所以在链接到进程空间 后,系统会为每个进程创建相应的数据段。也就是说如果一个共享库被N个进程链接,当这N个进程同时运行时,同时共享一个代码段,每个进程拥有一个数据段,系统中共有N个数据段。PIC即position independent code,使.so文件的代码段变为真正意义上的共享。如果编译时不加-fPIC,则加载.so文件的代码段时,代码段引用的数据对象需要重定位, 重定位会修改代码段的内容,这就造成每个使用这个.so文件代码段的进程在内核里都会生成这个.so文件代码段的copy。

加载方式

1. 静态加载

在程序编译的时候加上“-l”选项,指定其所依赖的动态库,这个库的名字将记录在ELF文件的.dynamic节。在程序运行时,loader会预先将程序所依赖的所有动态库都加载在进程空间中。

优点:动态库的接口调用简单,可以直接调用。

缺点:动态库的生存周期等于进程的生存周期,其加载时机不灵活。

2. 动态加载

在程序中编码来指定加载动态库的时机,经常使用的函数dlopen和dlclose。

优点:动态库加载的时机非常灵活,可以非常细致的定义动态库的生存周期。

缺点:动态库的接口调用起来比较麻烦,同时还要关注动态库的生存周期。

=====================================================

#include <dlfcn.h>

  void * dlopen( const char * pathname, int mode );

  函数描述:

  在dlopen的()函数以指定模式打开指定的动态连接库文件,并返回一个句柄给调用进程。使用dlclose()来卸载打开的库。

  mode:分为这两种

  RTLD_LAZY 暂缓决定,等有需要时再解出符号

  RTLD_NOW 立即决定,返回前解除所有未决定的符号。

  RTLD_LOCAL  不允许导出符号

  RTLD_GLOBAL 允许导出符号

  RTLD_NODELETE

RTLD_NOLOAD

RTLD_DEEPBIND          //具体含义可通过man查看dlopen函数说明

  返回值:

  打开错误返回NULL

  成功,返回库引用

  编译时候要加入 -ldl (指定dl库)

  int dlclose (void *handle);

  函数描述:

   dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。

在dlopen一个共享库时,

a、进程会加载该共享库的代码段和数据段,同时为这个共享库计数加1。

b、进程查找该共享库的dynamic节,查看其所依赖的共享库。

c、首先检查所依赖库是否已经被加载,如果已被加载,则为这个共享库计数加1。如果未被加载,则加载其代码段和数据段,然后为这个共享库计数加1。

d、再查找这些库所依赖的库。最终进程会为每个加载的共享库维护一个依赖的计数。

在dlclose共享库时:

a、首先将该共享库的计数减1,如果该共享库依赖计数为0,则卸载该共享库。

b、在dynamic节中,查找其所依赖的共享库。

c、为每个共享库的计数减1,如果该共享库依赖计数为0,则卸载该共享库。

d、重复上面的步骤。

  • 优点:

a、可以在程序启动的时候,减少加载库的数量,这样可以加快进程的启动速度和减少加载库的内存使用。

b、为进程提供了卸载共享库的机会,这样就可以回收共享库代码段和数据段所占用的内存。

  • 缺点:

对于程序员编码来讲,会产生一定的疑惑。一个static的对象的生存周期是贯穿在进程始终的,实际上不是这样。在动态库中的static对象,其生命周期等于该动态库的生命周期。采用静态链接的方式,动态库的生命周期等于进程的生命周期;而采用动态加载的方式,则是不同的。

参考:

《嵌入式Linux内存与性能详解》

 
 

Linux共享库两种加载方式简述的更多相关文章

  1. Linux驱动的两种加载方式过程分析

    一.概念简述 在Linux下可以通过两种方式加载驱动程序:静态加载和动态加载. 静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调用.静态加载的缺点是调试起来比较麻烦,每次修改一个地方都要重新 ...

  2. Xamarin Android Fragment的两种加载方式

    android Fragment的重点: 3.0版本后引入,即minSdk要大于11 Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套的Fra ...

  3. ios 图片的两种加载方式

    控件加载图片,plist,懒加载,序列帧动画,添加动画效果. IOS中有2种加载图片的方式. 方式一:有缓存(图片所占用的内存会一直停留在程序中) + (UIImage *)imageNamed:(N ...

  4. dll的两种加载方式(pend)+ delayload

    看过关于动态库的调用例子,于是决定动手做一做:dll的对外接口声明头文件,Mydll.h: //Mydll.h #include <stdio.h> #include <stdlib ...

  5. 渐进式jpeg(progressive jpeg)图片及其相关 --图片的两种加载方式

    渐进式jpeg(progressive jpeg)图片及其相关   一.基本JPEG(baseline jpeg)和渐进JPEG 网络上那些色色的照片都是.jpg格式的("色色"指 ...

  6. Qml文件的两种加载方式

    一种是QQmlApplicationEngine搭配Window,例如: #include <QGuiApplication> #include <QQmlApplicationEn ...

  7. Android Activity四种加载方式

    Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...

  8. Android学习笔记_50_(转 四种加载方式详解(standard singleTop singleTask singleInstance)

    Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...

  9. Android 四种加载方式详解(standard singleTop singleTask singleInstance) .

    Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...

随机推荐

  1. QTableWidget的使用和美工总结

    基本外观设置 FriendTable->setFrameShape(QFrame::NoFrame);  //设置边框 FriendTable->setHorizontalHeaderLa ...

  2. ARC和非ARC文件混编

    在编程过程中,我们会用到很多各种各样的他人封装的第三方代码,但是有很多第三方都是在非ARC情况下运行的,当你使用第三方编译时出现和下图类似的错误,就说明该第三方是非ARC的,需要进行一些配置. 解决方 ...

  3. C语言循环的嵌套

    注:参考网络资源拟制,如雷同请见谅循环的嵌套:一个循环体语句中又包含另一个循环语句,称为循环嵌套.嵌套注意事项:1.使用循环嵌套时,内层循环和外层循环的循环控制变量不能相同.2.循环嵌套结构的书写,最 ...

  4. Ant工具

    Ant工具 Ant是一种基于Java的build工具.理论上来说,它有些类似于(Unix)C中的make ,但没有make的缺陷.目前的最新版本为:Ant 1.9.4[1] .   Ant的概念 当一 ...

  5. c# 访问修饰符的访问权限

    1. 访问修饰符. 指定声明的类型和类型成员的可访问性. (1) public:是类型和类型成员的访问修饰符.公共访问是允许的最高访问级别.对访问公共成员没有限制. (2) private:是一个成员 ...

  6. iis6 下发布MVC2项目的方法

    1.安装MVC2运行库,否则会出现错误 [以下转载]http://blog.csdn.net/xw13106209/article/details/6323695 错误:”未能加载文件或程序集“Sys ...

  7. [转帖]音响及DarBee

    红外与蓝牙的差别 1.距离 红外:对准.直接.1—2米,单对单 红外线可以用你的手机摄像头看到  蓝牙:10米左右,可加强信号,可以绕弯,可以不对准,可以不在同一间房间,链接最大数目可达7个,同时区分 ...

  8. 比较两份文件的异同-beyond compare

    比较两份文件的异同-beyond compare 今天又学到一个知识,比较两次文件的 异同.  哈哈 谢谢领导

  9. 添加Pods后,import无提示的解决办法

    选择工程的 Target -> Build Settings 菜单,找到\”User Header Search Paths\”设置项 新增一个值"$(PODS_ROOT)" ...

  10. UISearchBar 光标不出现的问题

    app支持ios7,在UINavBar 里面加入搜索框,结果光标一直出现不了. 解决办法如下: searchBar.tintColor = [UIColor blueColor];