Linux(八)静态库,共享库与计算机基础知识

发布于:2025-03-19 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、库文件

1、库文件的概念

        库是一组预先编译好的方法的集合(也就是我们生成的.o文件);Linux系统存储库的位置一般在/lib和/usr/lib(64位系统/usr/lib64)库的头文件放在/usr/include

2、库的分类

静态库:libxxx.a(命名规则)

共享库:libxxx.so(命名规则)

下面我们就要学习静态库和共享库了,大家可以和小编一起准备下面这几个文件,用于静态库和共享库的练习。

//add.c
int add(int x,int y){
    return x+y;
}
//max.c
int max(int x,int y){
    return x>y?x:y;
}
//foo.h
int add(int x,int y);
int max(int x,int y);
//main.c
#include<stdio.h>
#include"foo.h"
int main(){
int a=5,b=10;
printf("a+b=%d/n",add(a,b));
printf("max=%d/n",max(a,b));
return 0
}

 大家可以向小编一样,先准备一个test081用于练习静态库,再准备一个test082用于练习共享库,你买那两个库放在一起出现问题。

二、静态库

1、静态库的生成与使用

1)将需要的库文件的所有.c文件编译成.o文件;

2)创建静态库(使用ar命令) 

ar crv libxxx.a xxx.o xxx.o

参数含义:

c:创建库

r:将方法添加到库

v:显示过程

3)静态库的使用

gcc -o main main.c -L. -lxxx

参数含义:

-L:指定库的存储位置,这里.是当前位置

-l:指定库的名称(不需要前面的lib和扩展名.a) 

那么我们来完整的看一下静态库的生成使用步骤吧

我们生成了静态库,那试一试没了.o文件是否还可以运行? 

2、静态库的缺点 

        当大家同时运行许多应用程序并且它们都使用来自同一个函数库的函数时,内存中就会有同一函数的多个副本。而且在程序文件自身中也有多份同样的副本,这将消耗大量宝贵的内存和磁盘空间。

三、共享库

1、共享库的生成与使用

1)将所有.c文件编译成.o文件;

2)将所有目标文件打包生成共享库

gcc -shared -fPIC -o libxxx.so xxx.o xxx.o

3)共享库的使用:

gcc -o main mian.c -L路径 -l库名

2、注意

在上面的图片我们会发现,使用共享库编译的main文件无法运行,这是为什么呢?

在这里给大家叫一个命令,ldd  需要运行的文件名,它是用来查看我们使用了哪些共享库的

然后,我们就会发现我们使用的这个共享库没有被找到,这是为什么呢?

在学习(二)的目录结构时,小编提到过lib是用来存放库文件的,即使我们在刚刚的命令里已经告诉了计算机这个库的位置,但计算机只要没在lib中找到,就不会编译。

 

因此,我们要报libfoo.so放到/usr/lib下看看;根据下图,我们发现放到lib后就可以运行了,但是小编不建议大家把自己写的共享库放到lib里,因为lib存放的是已经很完善很全面的库文件,我们写的写很简单,不要放在一起混淆了。当我们删除libfoo.so后,main文件又不可以运行了。

我们现在已经学习完了两种库,那它们都有什么区别呢?

【静态库和共享库的区别】 

        共享库如果10个应用程序共享,那么磁盘上只有一份共享的库文件,而且运行加载时在内存中只加载了标记了的这一份库文件;
        而静态库,就是这10个应用程序都包含了这个库文件,那么10份的库文件都放在磁盘上了(占用磁盘空间),而且运行加载的时候占用内存空间(10份库文件都要加载);

        总结一下上面两段,静态库是包含,共享库是标记

        共享库便于升级。

        静态库的好处是在目标机器上运行程序的时候,就不再依赖于这个机器的空间,因为已经将方法都包含进来了;而共享库就是只有一份共享,比较节省空间,但是坏处就是运行的时候,这个主机上必
须有这个库文件,没有程序就会运行失败;

【面试题分享】

1、问题:什么是库文件,说一下静态库与共享库的区别,并给出生成静态库与共享库的示例命令?

解答:

(1)库是一组预先编译好的方法的集合;

(2)共享库如果10个应用程序共享,那么磁盘上只有一份共享的库文件,而且运行加载时在内存中
只加载了标记了的这一份库文件;而静态库,就是这10个应用程序都包含了这个库文件,那么10份
的库文件都放在磁盘上了(占用磁盘空间),而且运行加载的时候占用内存空间(10份库文件都要加
载);

(3)生成静态库的方法:1)先将需要生成库文件的所有.c文件编译成.o文件;2)创建静态库(使用ar命令):ar crv libxxx.a xxxx.o xxx.o;3)静态库的使用:gcc-o main main.c-L .- lxxx (其中 :- L:指
定库的存储位置 -I:指定库的名称(不需要前面的lib和扩展名.a))

(4)生成共享库的方法:1)将所有的.c文件编译成目标文件.o 2)将所有目标文件打包生成共享库:gcc
-shared -fPIC -o libxxx.so XXX.O XXX.O注意:共享库必须要放到标准路径下:sudo mv libxxx.so/usr/lib;3)共享库的使用:gcc-o main main.c-L路径-I库名

2、问题:什么是静态链接和动态链接,优缺点分别是什么?

1、静态链接:

函数和数据被编译进一个二进制文件。在使用静态库的情况下,在编译链接可执行文件时,链
接器从库中复制这些函数和数据并把它们和应用程序的其它模块组合起来创建最终的可执行文
件。
空间浪费:因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对
同一个目标文件都有依赖,会出现同一个目标文件都在内存存在多个副本;
更新困难:每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。
运行速度快:但是静态链接的优点就是,在可执行程序中已经具备了所有执行程序所需要的任何
东西,在执行的时候运行速度快。

2、动态链接:

动态链接的基本思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将它们链接
在一起形成一个完整的程序,而不是像静态链接一样把所有程序模块都链接成一个单独的可执
行文件。
共享库:就是即使需要每个程序都依赖同一个库,但是该库不会像静态链接那样在内存中存在多份
副本,而是这多个程序在执行时共享同一份副本 ;.
更新方便:更新时只需要替换原来的目标文件,而无需将所有的程序再重新链接一遍。当程序下一
次运行时,新版本的目标文件会被自动加载到内存并且链接起来,程序就完成了升级的目标。
性能损耗:因为把链接推迟到了程序运行时,所以每次执行程序都需要进行链接,所以性能会有一
定损失。

四、计算机基础知识

1、计算机组成的五大部件

1)运算器:也叫算数逻辑单元,完成对数据的各种常规运算,如加减乘除,也包括逻辑运算,
移位,比较等。

2)控制器:它是整个计算机系统的控制中心,它指挥计算机各部分协调地工作,保证计算机
按照预先规定的目标和步骤有条不紊地进行操作及处理。

3)存储器:存储程序和各种数据。

4)输入设备:把人所熟悉的信息如,图片,声音,文字,转换为计算机能够识别的信息存储起来。

5)输出设备:把计算机机能识别的信息转换为人能识别的信息,进行呈现。

2、一台计算机可以抽象成下图:

        CPU中包含控制器和运算器,内存就是存储器.I/O设备就是输入设备和输出设备,如:键盘,显示器,鼠标,硬盘,网卡;

3、系统总线

1)数据总线:用来在各个功能部件中间传输数据,是双向传输总线;

2)地址总线:用来指出数据总线上的源数据或目的数据在主存单元的地址或IO设备的地址;

3)控制总线:由于各个连接在数据总线和地址总线的部件都是共享这两类总线的,那么
在某一时刻由谁来使用,就是控制总线负责完成的。

4、指令相关概念

1)指令:是指示计算机执行某种操作的命令。一条指令通常由两部分构成:地址码和操作
码。

2)程序:由一条一条的指令构成。

3)指令周期:cpu每取出并执行一条指令所需的全部时间称为指令周期。

4)指令系统:计算机能够执行的全部指令的集合称为该计算机的指令系统。

5)RISC:精简指令系统计算机。(考点)RISC技术是用20%的简单指令的组合来实现不常用的80%的那些指令功能,但这不意味着RISC技术就是简单地精简其指令集。在提高性能方面,RISC技术还采取了许多有效措施,最有效地方法就是减少执行地执行周期数。

6)CISC:复杂指令系统计算机。(考点)

7)程序和指令:高级语言 汇编助记符 机器指令

五、进程的基础知识(重要考点)

这是小编第二次向大家提到进程了,我们这次就要向大家介绍一下进程啦!

1)进程:

        一个正在运行中的程序;

2)PCB:

        进程控制块,进程描述符(PID:进程唯一的标识符)进程控制块是用一个结构体struct task_struct来实现;

3)进程的状态:(考点)

                        就绪、阻塞、运行

在这个图里,有一个时间片完,这是什么意思呢?

        这是时间片轮转调度;时间片轮转调度是一种最古老,最简单,最公平且使用最广的算法。每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。

4)并发与并行

   (我们用图片来了解一下)

5)操作系统发展史

操作系统:管理计算机上的软硬件资源,为用户提供一个交换的接口;
(1)串行处理;
(2)简单批处理;
(3)多道程序设计
(4)分时系统

六、主函数的三个参数

1、主函数的三个参数的含义:

argc:主函数的参数个数

argv:主函数的参数内容

envp:环境变量

我们用代码来展示一下:

#include<stdio.h>
   
  int main(int argc,char *argv[],char *envp[])
  //int main(int argc,char **argv,char **envp)//上下一样
  {
     printf("argc = %d\n",argc);
     for(int i=0;i<argc;i++){
       printf("argv[%d]=%s\n",i,argv[i]);
     }
     printf("argc = %d\n",argc);
     for(int i=0;envp[i]!=NULL;i++){
        printf("envp[%d]=%s\n",i,envp[i]);
     }
    return 0;
  }

环境变量太多啦,这里小编就不截全了,只展示头和尾

 

2)总结

argc:传递给主函数的参数个数
argv:传递给主函数的参数列表,字符指针数组,给主函数传递的参数都是字符串;(以NULL结尾)
envp:继承的环境变量列表,以NULL结尾;

【小编有话说】

今天的内容就结束啦,有很多需要大家自己读和背的知识点,一定要看哦!!!

那就这样吧,不要忘记点赞关注哦!!!


网站公告

今日签到

点亮在社区的每一天
去签到