Linux系统原理浅谈

  1. CPU

     

    1. CPU和各个存储器

       

      1. 寄存器:接近于CPU的工作频率,是CPU的本地存储器,位于运算器和控制器中,在进程的切换时,寄存器会被清空
      2. 一级缓存:比寄存器稍慢,频率同样接近于CPU,只能用于缓存数据,不能像寄存器一样修改数据,各个核心都有自己的私有一级缓存,进程切换时不被清空
      3. 二级缓存:比一级缓存慢,多个核心都有自己私有的二级缓存
      4. 三级缓存:比二级缓存慢,如果有多个核心的CPU,那么三级缓存为多个核心的共享区域

         

        1. 多颗cpu共享三级缓存或是内存的时候,就会出现了一个问题,即资源征用。
        2. 现在在很多CPU上都引入了NUMA机制(非一致性内存访问):

           

          1. 将三级缓存分割,分别让不同的CPU占用不同的内存地址,这样我们可以理解他们都有自己的三级缓存区域,不会存在资源抢夺的问题,但是要注意的是他们还是同一块三级缓存。就好像北京市有朝阳区,丰台区,大兴区,海淀区等等
          2. 那么问题来了,基于重新负载的结果,如果cpu1运行的进程被挂起,其地址在他自己的缓存中是有记录的,但是当cpu2再次运行这个程式的时候被CPU2中的缓存没有该进程的缓存,又是如何处理的呢?
          3. 这就没法了,只能从CPU1的三级区域中复制一份地址过来或是移动过来一份让CPU2来处理,这个时候是需要一定时间的。所以说重新负载均衡会导致CPU性能降低。这个时候我们就可以用进程绑定来实现,让再次处理该进程的时候还是用之前处理的CPU来处理。即进程和CPU的亲缘性
      5. 内存:比CPU的频率慢的多,如果直接让内存和CPU相连,那么会导致计算机性能很差,因为CPU发出取指令的信息后,需要等待很长时间后内存才吐出数据给CPU,假设CPU的工作频率在1ns一次那么需要等10个时钟周期内存才能响应,内存的工作频率为10ns,所以需要加中间层来按照程式的局部特性缓存数据
      6. 固态硬盘或机械硬盘
      7. 程式局部性原理:

         

        1. 空间局部性:程式是由指令和数据组成的。空间局部性指的是一个数据被访问到之后,那么离这个数据很近的其他数据随后也可能会被访问到
        2. 时间局部性:一般而言当一个程式执行完毕后,可能很快会被访问到。数据也是同样的原理,一个数据的被访问到,很可能会再次访问到
        3. 正是因为程式局部性的存在,所以使得无论是在空间局部性或者时间的局部性的角度来考虑,一般而言我们都需要对数据做缓存
      8. CPU和各个存储器的工作逻辑

         

        1. CPU能操作数据是在寄存器中操作的,操作动作如:1+1修改某个变量的值,修改的值最终被存储在内存中,内存再同步到磁盘(磁盘为外部的IO设备可以不用考虑,因为计算机的核心就是运算器、控制器和存储器)
        2. 首先寄存器中需要从一级缓存中取数据,如果1级没有到2级取,2级没有到3级,直到内存。寄存器将数据修改完成,会将结果保存到1级,2级,3级,内存;CPU在处理完数据后,会有两种写数据的方式到缓存或内存

           

          1. 通写:写到内存中,CPU才能继续其他工作,因为结果保存在1级或2级那么如果该进程被调度到其他核心上,那么就找不到上一次运行的结果了,所以需要让数据尽快的写到内存中
          2. 回写:写到一级缓存中,就告诉CPU完成,性能很好
    2. CPU多核心和进程线程

       

      1. 多核心的CPU的每个核心都相当于一个CPU,如果在一个web服务器上,有100个进程,其中97个进程是长时间处于睡眠状态,2个进程需要偶尔运行一下,1个处于超级繁忙状态,别的进程都不需要工作,就这一个web进程需要占用大量的额CPU时间,但CPU有4个核心,这4个核心就不能得到充分利用,因此如果要某个服务器上只有单个进程繁忙时,发挥CPU的最大用途,就需要程式并行编程,让这个进程产生多个线程跑在多个核心的CPU上
      2. 线程的产生是将进程中串行的指令执行流做成多个并行的指令执行流,多个执行流互不相关,比如400个指令的进程,将它分为100个一组的4个线程,这样的编程叫做并行编程。但这样存在着问题,因为线程与线程之间存在着一定程度上的联系,比如1.第二个线程可能需要第一个线程的结果,2.线程之间是共享进程资源的,如进程打开的文件描述符,当一个线程在操作一个文件的时候,另外的线程只能是等待状态。所以程式员都必须要精细的设计程式,否则一个进程中的多个线程可能彼此之间协调就不流畅。比如在我们的网路IO模型中,web服务器的一个进程生成多个线程来处理用户请求时,好在大多用户的请求都是get读操作,那么多个线程就可以同时读取数据,挣用资源的时间并不多,所以这样的程式设计模式,就实现了网络IO模型中的多路复用模型
      3. 当CPU将某个线程中的指令调度到某个核心中执行完后,下一次调度可能会不在同一个核心,这样导致缓存无法命中,因为在执行指令时,因为内存速度相对于CPU的速度是很慢的,所以在获取数据时先从一级缓存中获取,如果没有然后2级,再没有最后从内存中获取,如果调往另外的核心,那么另外核心上的123级的缓存中将没有之前程式需要的缓存数据,所以需要实现进程和CPU绑定的机制,相当于是nginx中的会话绑定一样
      4. 多核心CPU在调度线程来运行时,通常都相同于nginx中的调度一样,CPU的哪个核心闲就往哪个核心上调度,并且每一秒中balance一次,每个核心上都有两个进程队列(等待队列和空闲队列),如果有400个进程每个核心上有100个进程在排队,如果某个时刻后,一个核心上的进程全部运行完毕,而一个核心上依然有很多进程没有运行完,那么内核会rebalance一次
      5. 进程的上下文切换:

         

        1. 在一个进程要调度到CPU上来运行的过程查看
        2. 当进程A的运行时间片结束后,会有另外一个进程B调度到CPU上运行,而进程A的运行的状态信息(如在运算器中执行的哪条指令,在控制器中下一条指令的地址),都会被保存到进程的PCB(PCB存在于内存)中,第二次将进程A调度到CPU上运行时,会从内存中A的PCB的现场状态信息取到CPU中的寄存器中,继续之前的操作,这个叫进程的上下文切换,进程的上下文切换的过程是很繁琐的
        3. HTTPD的prefork模型是1个进程处理1个用户的请求,如果有1000个用户并发访问,那么进程的上下文切换会很频繁,而nginx由一个进程来处理多个用户的请求,所以不用再切换省去了大量的切换时间

 

  1. IO设备:

     

    1. 由设备控制器和设备本身组成,相对于CPU和内存,这样的设备属于外部设备
    2. 设备控制器:集成在主板的一块芯片活一组芯片。负责从操作系统接收命令,并完成命令的执行。比如操作系统要读取磁盘的某个文件,控制器在接收到命令后,将命令转化为对应物理设备的物理操作

       

      1. 设备控制器的驱动程式:设备控制器将操作系统的命令转化为对应物理设备的电气操作,是依赖于控制器中的驱动程式来完成的(而不是内核),所以驱动程式应该由设备生产商来研发,但是由于有些驱动程式过于通用,所以很多驱动程式被集成在了内核中
      2. 设备控制器的寄存器:每个控制器都有少量的用于通信的寄存器(几个到几十个不等)。这个寄存器是直接集成到设备控制器内部的。如:磁盘控制器,它内部都会有一些空间用于存储指定磁盘地址,扇区计数,读写方向等相关操作信息,这些空间都是寄存器。所以任何时候想要激活控制器,设备驱动程式从操作系统中接收操作指令,然后将它转换成对应设备的电气操作指令,并把这样的操作指令放置在寄存器中,硬件设备才能完成操作。
    3. 设备本身:其有自己的接口,但是设备本身的接口并不可用,它只是一个物理接口。如IDE接口
    4. 磁盘缓存:又称磁盘快取,实际上就是将下载到的数据先保存于系统为软件分配的内存空间中(这个内存空间被称之为“内存池”),当保存到内存池中的数据达到一个程度时,便将数据保存到硬盘中。这样可以减少实际的磁盘操作,有效的保护磁盘免于重复的读写操作而导致的损坏
    5. 从内存写数据到磁盘同样有两种方式:通写(内核控制内存中的数据写入到磁盘的某个位置则完成工作)、回写(内核控制内存中的数据写入到磁盘缓存,内核则释放,之后磁盘控制器自己将磁盘缓存中的数据写入磁盘)
    6. 实现输入和输出

       

      1. 每个寄存器表现为一个IO地址端口。所有的寄存器组合称为设备的I/O地址空间,也叫I/O端口空间,设备的I/O端口没法事前分配,因为各个主板的型号不一致,所以我们需要做到动态指定。电脑在开机的时候,每个IO设备都要向总线的I/o端口空间注册使用I/O端口。能注册的动态端口有2^16次方个,即65535个端口,他们形成了设备的I/O地址空间

Linux系统原理浅谈 

  1. 实现I/O设备的输入和输出的方式:

     

    1. 轮询:

       

      1. CPU要不断地查询外设的状态,当外设未准备好数据时,CPU就只能循环等待,不能执行其它程序,这样就浪费了CPU的大量时间,降低了主机的利用率
    2. 中断:

       

      1. 为了解决以上这个矛盾,我们提出了中断传送方式,即当CPU进行主程序操作时,外设的数据已存入输入端口的数据寄存器;或端口的数据输出寄存器已空,由外设通过中断控制器向CPU发出中断请求信号,CPU在满足一定的条件下,暂停执行当前正在执行的主程序,转入执行相应能够进行输入/输出操作的子程序,待输入/输出操作执行完毕之后CPU即返回继续执行原来被中断的主程序。这样CPU就避免了把大量时间耗费在等待、查询状态信号的操作上,使其工作效率得以大大地提高。 能够向CPU发出中断请求的设备或事件称为中断源,这个过程叫中断处理
      2. 主板通常有一个独特的设备,叫做可编程中断控制器。这个中断控制器可以通过某个针脚和CPU直接进行通信,能够触发CPU发生某个位置偏转,进而让CPU知道某个信号到达。中断控制器上会有一个中断向量(每一个I/O设备在启动时,要向中断控制器注册一个中断号,这个号通常是唯一的。通常中断向量的每一个针脚都是可以识别多个中断号的),中断向量也可以叫中断号
      3. 设备向中断控制器发出中断请求,中断控制器通过中断向量识别这个请求是哪个设备发来的,然后通过某种方式通知给CPU,让CPU知道具体哪个设备中断请求到达了。这个时候CPU可以根据设备注册使用I/O端口号,从而就能获取到设备的数据了。(注意:CPU在接收到中断请求后,会暂停当前进程的执行,内核开始调入到CPU上运行,之后内核会发出响应的指令,让相应的设备寄存器上的数据读入内存)

         

        1. 例:一个网卡接收到外来IP的请求,数据先到达网卡自己的缓存区,CPU中断当前进程,转为内核工作,内核将网卡缓存中的数据复制到内核的内存空间中,发现这个是网络报文,就开始判断IP是不是本机,如果是就开始拆报文,最后会获取到一个端口号,然后转为该端口对应的进程在CPU上运行
      4. 内核中断处理分为两步:

         

        1. 中断上半部分,当用户请求到达网卡时,CPU中断开始,网卡缓存区的数据会被立即复制到内存中,如果不立即处理网卡发出的中断信号将会消失,之后不发再获取网卡缓存中的数据,这个我们称之为中断的上半部分
        2. 中断下半部分,将数据复制到内存后不一定立即处理,因为很有可能继续处理之前中断的进程,而真正处理这个请求报文的过程叫做下半部份
    3. DMA:

       

      1. 中断的问题:如果某个请求是上传请求,发送的是一个压缩包,如果有10M,单个报文只能传送1000个Byte,所以就只能被封装为很多的数据包,每个数据包到达网卡都发送中断请求,那么CPU会不断的处理中断。因为中断存在的问题,所以有了直接内存访问DMA
      2. 为了不让网卡收到每一个数据包时都发送一个中断请求,内核通过CPU告诉网卡,在内核内存中有一大段空间,让网卡自己将数据复制到这段空间,这样的话网卡就需要有使用总线的权限和功能,即能对在总线上能寻址,发送控制信息,和数据传输,但CPU是总线的控制者,在某一时刻到底,哪个I/O设备能使用总线是由CPU的控制器来决定的。那么就和CPU争用总线了
      3. 因此,I/O设备自带的一个具有智能型的控制芯片(称之为直接内存访问控制器),当某一个时刻需要处理中断上半部分时,内核会告知某一个DMA设备,接下来总线归这个DMA设备使用,并且告知其可以使用的内存空间,用于将I/O设备的数据读取到内存空间中去。当DMA的I/O设备将数据读取完成后,会发送消息告诉内核以及完成了读取操作,而中断下半部分的处理就来交个内核处理。现在大多数设备都是用DMA控制器的,比如:网卡,硬盘等等
  1. 总线:

     

    1. 总线(Bus)由导线组成的传输线束,是一种内部结构, 它是cpu、内存、输入、输出设备传递信息的公用通道,主机的各个部件通过总线相连接,外部设备通过相应的接口电路再与总线相连接,从而形成了计算机硬件系统。按照计算机所传输的信息种类,计算机的总线可以划分为数据总线(传输数据信息)、地址总线(传输数据地址,完成对设备的寻址功能)和控制总线(传输控制信号,协调各个设备使用总线)
    2. 使用多宽的总线是由CPU字长(CPU的字长:CPU在单位时间内(同一时间)能一次处理的二进制数的位数)决定,比如32bit字长的CPU,就只能使用32bit的地址总线(表示虚拟地址空间是 0 – 2^32,也就是最大4GByte的空间)、32bit的数据总线和32bit的控制总线
    3. 工作原理:如果说主板(Mother Board)是一座城市,那么总线就像是城市里的公共汽车(bus),能按照固定行车路线,传输来回不停运作的比特(bit)。这些线路在同一时间内都仅能负责传输一个比特。因此,必须同时采用多条线路才能传送更多数据,而总线可同时传输的数据数就称为宽度(width),以比特为单位,总线宽度愈大,传输性能就愈佳。总线的带宽(即单位时间内可以传输的总数据数)为:总线带宽 = 频率 x 宽度(Bytes/sec)。当总线空闲(其他器件都以高阻态形式连接在总线上)且一个器件要与目的器件通信时,发起通信的器件驱动总线,发出地址和数据。其他以高阻态形式连接在总线上的器件如果收到(或能够收到)与自己相符的地址信息后,即接收总线上的数据。发送器件完成通信,将总线让出(输出变为高阻态)

 

  1. 内存:

Linux系统原理浅谈 

  1. 以32bit地址空间为例,如果应用程式空间只有一个进程在运行,那么这个进程可以随意使用这段空间,即想申请哪段空间就申请哪段空间,但有两个问题:

     

    1. 一个进程使用时,而应用程式申请了超出物理内存空间范围,但在寻址范围内时,如:物理内存只提供了2G,但是32bit的CPU分析程式的指令后,寻址到了第3G的那个空间,这样的问题在早些年是无法解决的,所以程序员在开发程式的时候,需要按照物理内存的宽度来开发
    2. 多个进程同时使用这段空间时:这样进程所使用的空间中的数据,有可能被其他进程所修改
  2. 虚拟内存空间:对于以上存在的问题,所以有了虚拟内存空间

     

    1. 只要不是内核使用的物理内存空间我们称之为用户空间。内核会把用户空间的物理内存切割成固定大小的页框(即page frame),就是切割成一个固定大小的存储单位,比默认的单个存储单元(默认是一个字节,即8bit)要大.通常每4k一个存储单位。每一个页框作为一个独立的单元向外进行分配,且每一个页框也都有其编号。【举个例子:假设有4G空间可用,每一个页框是4K,一共有1M个页框。】这些页框要分配给不同的进程使用。

       

      1. 页框(page frame):

         

        1. 内存管理的概念,CPU中添加了能自动把虚拟内存(即逻辑地址)地址转化为物理内存地址的电路,为了简化这种电路,就把RAM划分为长度为4KB或8KB的块,这种块就叫页框
        2. 内核以页框为基本单位管理物理内存,分页单元中,页指一组数据,而存放这组数据的物理内存就是页框,当这组数据被释放后,若有其他数据请求访问此内存,那么页框中的页将会改变
    2. 对于每个进程来说,它使用到的都是虚拟地址,每个进程都看到一样的虚拟地址空间(一个连续完整的地址空间),虚拟地址空间不需要和物理地址空间一样大小。进程实际上是分配到了物理内存中,MMU将进程的虚拟内存地址转化成物理内存地址将其分别存储到地址所指向的位置。进程进行写入内存是被离散存储到物理内存。哪有空余内存就往哪存取

       

      1. 假设有4G内存,操作系统占用了1个G,剩余的3G物理内存分配给用户空间使用。对于32位计算机系统来说,它的虚拟地址空间是 0 – 2^32,也就是0 – 4G。对于64位的计算机系统来说,理论的虚拟地址空间是 0 – 2^64,远高于目前常见的物理内存空间
      2. 每一个进程在运行时,不会把程式都装载到内存,而是只加载一部分指令到内存,虽然可用3G但不会使用到3G,如图:仅将一些代码,所用到的数据和变量,打开的文件加载到内存,即代码段、数据段、堆和栈,并不需要太多的空间,大概几个页面(虚拟空间划分的存储单位叫页面,同物理空间划分的页框一样)
      3. 进程空间结构:

         

        1. 预留空间
        2. 栈(变量存放处)
        3. 共享库
        4. 堆(打开的文件,文件中的数据流存放处)
        5. 数据段(全局的静态变量存放处)
        6. 代码段

Linux系统原理浅谈 

  1. CPU在执行进程的指令时获取其数据时有以下几步:

     

    1. 进程指令中地址都是虚拟地址,把进程指令使用的虚拟地址通过MMU转换成物理地址
    2. 把物理地址映射到高速缓存的缓存行,如1,2,3级缓存,即在这些高速缓存中查找有没有该物理地址对应的数据
    3. 如果高速缓存命中就返回
    4. 如果不命中,就产生一个缓存缺失中断,从主存相应的物理地址取值,并加载到高速缓存中。数据拿到后CPU从中断中恢复,继续执行中断前的指令,所以高速缓存是和物理地址相映射的

Linux系统原理浅谈 

 

  1. 进程

     

    1. 进程运行实际上就是把有限的抽象资源(cpu,memory等等)分配给进程。我们把这些抽象资源统称为资源集,资源集包括:

       

      1. cpu时间片;
      2. 内存地址:抽象成虚拟地址空间 ( 如32位操作系统,支持4G空间,内核占用1G空间,进程也会默认自己有3G可用,事实上未必有3G空间,因为你的电脑可能会是小于4G的内存。)
      3. I/O:Linux中所有的对象都被抽象为文件,一个进程运行时,将会使用到比如IO设备、普通文件(实际上是数据流)、套接字(socket文件)之类的,所以需要打开的多个文件,即是通过fd(文件描述符,file descriptor)打开指定的文件,有三个的fd是固定的,每个进程都需要标准的输入输出,即0、1、2。我们把文件分为三类:正常文件、设备文件、管道文件

 

  1. MMU

     

    1. 现代操作系统普遍采用虚拟内存管理(Virtual Memory Management)机制,这需要处理器中的MMU(Memory Management Unit,内存管理单元)提供支持
    2. 首先引入两个概念,虚拟地址和物理地址。如果处理器没有MMU,或者有MMU但没有启用,CPU执行单元发出的内存地址将直接传到芯片引脚上,被内存芯片(以下称为物理内存,以便与虚拟内存区分)接收,这称为物理地址(Physical Address,以下简称PA),如下图所示。

Linux系统原理浅谈

  1. 如果处理器启用了MMU,CPU执行单元发出的内存地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address,以下简称VA),而MMU将这个地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将VA映射成PA,如下图所示。
  2. 如果是32位处理器,则内地址总线是32位的,与CPU执行单元相连(图中只是示意性地画了4条地址线),而经过MMU转换之后的外地址总线则不一定是32位的。也就是说,虚拟地址空间和物理地址空间是独立的,32位处理器的虚拟地址空间是4GB,而物理地址空间既可以大于也可以小于4GB。
  3. MMU将VA映射到PA是以页(Page)为单位的,32位处理器的页尺寸通常是4KB。例如,MMU可以通过一个映射项将VA的一页0xb7001000~0xb7001fff映射到PA的一页0x2000~0x2fff,如果CPU执行单元要访问虚拟地址0xb7001008,则实际访问到的物理地址是0x2008。物理内存中的页称为物理页面或者页帧(Page Frame)。虚拟内存的哪个页面映射到物理内存的哪个页帧是通过页表(Page Table)来描述的,页表保存在物理内存中,MMU会查找页表来确定一个VA应该映射到什么PA。
  4. 操作系统和MMU是这样配合的:

     

    1. 操作系统在初始化或分配、释放内存时会执行一些指令在物理内存中填写页表,然后用指令设置MMU,告诉MMU页表在物理内存中的什么位置。
    2. 设置好之后,CPU每次执行访问内存的指令都会自动引发MMU做查表和地址转换操作,地址转换操作由硬件自动完成,不需要用指令控制MMU去做。
  5. 我们在程式中使用的变量和函数都有各自的地址,程式被编译后,这些地址就成了指令中的地址,指令中的地址被CPU解释执行,就成了CPU执行单元发出的内存地址,所以在启用MMU的情况下,程式中使用的地址都是虚拟地址,都会引发MMU做查表和地址转换操作。那为什么要设计这么复杂的内存管理机制呢?多了一层VA到PA的转换到底换来了什么好处?All problems in computer science can be solved by another level of indirection.还记得这句话吗?多了一层间接必然是为了解决什么问题的,等讲完了必要的预备知识之后,将在MMU(二)讨论虚拟内存管理机制的作用。
  6. MMU除了做地址转换之外,还提供内存保护机制。各种体系结构都有用户模式(User Mode)和特权模式(Privileged Mode)之分,操作系统可以在页表中设置每个内存页面的访问权限,有些页面不允许访问,有些页面只有在CPU处于特权模式时才允许访问,有些页面在用户模式和特权模式都可以访问,访问权限又分为可读、可写和可执行三种。这样设定好之后,当CPU要访问一个VA时,MMU会检查CPU当前处于用户模式还是特权模式,访问内存的目的是读数据、写数据还是取指令,如果和操作系统设定的页面权限相符,就允许访问,把它转换成PA,否则不允许访问,产生一个异常(Exception)。异常的处理过程和中断类似,不同的是中断由外部设备产生而异常由CPU内部产生,中断产生的原因和CPU当前执行的指令无关,而异常的产生就是由于CPU当前执行的指令出了问题,例如访问内存的指令被MMU检查出权限错误,除法指令的除数为0等都会产生异常。

 

  1. 处理器模式

     

    1. 通常操作系统把虚拟地址空间划分为用户空间和内核空间,例如x86平台的Linux系统虚拟地址空间是0x00000000~0xffffffff,前3GB(0x00000000~0xbfffffff)是用户空间,后1GB(0xc0000000~0xffffffff)是内核空间。用户程式加载到用户空间,在用户模式下执行,不能访问内核中的数据,也不能跳转到内核代码中执行。这样可以保护内核,如果一个进程访问了非法地址,顶多这一个进程崩溃,而不会影响到内核和整个系统的稳定性。CPU在产生中断或异常时不仅会跳转到中断或异常服务程式,还会自动切换模式,从用户模式切换到特权模式,因此从中断或异常服务程式可以跳转到内核代码中执行。事实上,整个内核就是由各种中断和异常处理程式组成的。总结一下:在正常情况下处理器在用户模式执行用户程式,在中断或异常情况下处理器切换到特权模式执行内核程式,处理完中断或异常之后再返回用户模式继续执行用户程式。
    2. 段错误我们已经遇到过很多次了,它是这样产生的:

       

      1. 用户程式要访问的一个VA,经MMU检查无权访问。
      2. MMU产生一个异常,CPU从用户模式切换到特权模式,跳转到内核代码中执行异常服务程式。
      3. 内核把这个异常解释为段错误,把引发异常的进程终止掉。

 

本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/94265

(1)
DPingDPing
上一篇 2018-04-01
下一篇 2018-04-01

相关推荐

  • 软件包管理 rpm yum的使用

    软件包管理 链接主要作用是吧各个模块之间互相引用的部分处理好, 使得各个模块之间能够正确的链接,分为静态和动态 静态链接  以.a为后缀  把程序对应的依赖库复制到包           升级难 需重新编译  占用空间多 迁移容易 动态链接  以.so为后缀 把依赖加做动态链接    占用空间少  升级方便           若一个库被删,那么所有依赖此库…

    Linux笔记 2018-04-22
  • 转义字符Escape character在正则中的用法

    通过()的在基本正则和扩展正则中的不同使用,详细介绍了转义字符的使用注意事项

    Linux笔记 2018-04-13
  • 关于grep 与 正则表达式的那些事

    首先要记住的是: 正则表达式与通配符不一样,它们表示的含义并不相同! 正则表达式只是一种表示法,只要工具支持这种表示法, 那么该工具就可以处理正则表达式的字符串。vim、grep、awk 、sed 都支持正则表达式,也正是因为由于它们支持正则,才显 得它们强大grep (缩写来自Globally search a Regular Expression and…

    Linux笔记 2018-04-08
  • RIAD及逻辑卷理论

    该篇内容纯理论知识,部分内容引起不适,望谅解

    Linux笔记 2018-04-29
  • Linux的发展演变及其哲学思想

    1:计算机组成及功能
    2:Linux发行版之间的联系与区别
    3:Linux的哲学思想
    4:Linux中基础命令介绍
    5:Linux中获取命令的帮助信息

    Linux笔记 2018-06-23
  • 第三周作业

    时间不够啊,,先搭个架子

    Linux笔记 2018-07-07