程序员的自我修养——链接,装载与库(一)

程序员的自我修养——链接,装载与库这本书看了差不多有一个多月了,这本书讲了很多计算机底层的知识,也补充了我的知识盲区。但是感觉看完以后前面有的知识有遗忘,因此就想好好的总结一下,也可以更好的理解这本书。

  • 计算机三个最重要的硬件是:中央处理器CPU,内存和I/O控制芯片。

  • 为了协调I/O设备与总线之间的速度,也为了能够让CUP能够和I/O通信,每个设备都有一个I/O控制器。

  • 计算机系统的软件体系结构的设计是分层次的,每个层次之间需要相互的通信,互相通信就需要协议,我们称其为接口。

  • 应用程序和操作系统内核通过中间的桥梁系统调用接口进行交互,系统调用是通过中断来实现的。

  • 操作系统的功能是:提供抽象的接口和控制硬件的资源。

  • 硬件驱动程序对硬件进行管理,硬件驱动程序是操作系统内核的一部分。

  • 硬盘的基本存储单位是扇区。

  • 早期的内存分配机制存在很多问题,第一,地址空间不隔离。第二,内存使用效率低。第三,程序运行的地址不确定。因此,我们把CPU分配的地址看作一种虚拟地址(虚拟地址往往比物理地址大很多),然后通过某些映射的方法,将这个虚拟地址映射到物理地址,这样就可以解决物理内存地址不足的问题。

  • 地址空间分为两种:虚拟地址空间和物理地址空间。物理地址空间是实际存在的地址空间。虚拟地址空间是指虚拟的,人们想象出来的地址空间,其实它并不存在,每个进程都有自己独立的虚拟地址空间,而且每个进程只能访问自己的地址空间。

  • 我们可以使用分段的方法,把程序所需要的虚拟地址空间的大小映射到物理地址空间。分段的方法是将虚拟地址空间进行分段(以程序为单位),然后通过映射函数一一映射到物理地址空间。分段的方法内存的使用效率较低。会产生大量的外部碎片。

  • 分页的基本方法是把虚拟地址空间等分成固定的页,把常用的数据和代码页装载到内存中,不常用的代码和数据保存到磁盘里,需要时从磁盘中取出即可。我们把虚拟空间中的页叫虚拟页,把物理空间的页叫做物理页。每个页我们可以设置其属性。

  • 线程有时被称为轻量级进程,是程序执行流的最小单元,线程由线程ID,指令指针(程序计数器),寄存器集合和堆栈组成。线程可以共享进程的内存空间。线程可以访问进程内存里面的所有数据。每个线程都有自己私有的内存空间(包括栈,线程局部存储和寄存器)。

  • 通过对CPU切换对线程进行调度。

  • 线程至少包括三种状态:运行,就绪,等待。当运行态的线程的时间片使用完后,该线程会进入到就绪态。

  • 线程调度大都都有优先级调度和轮转法的思想。每个线程都拥有各自的优先级,具有高优先级的线程会更早的执行。

  • 频繁等待的线程成为I/O密集型线程。很少等待的线程称为CPU密集型线程。

  • 饿死是指线程的优先级相对于其他线程较低,以至于长时间无法被执行,因此导致了该线程进入饿死状态。

  • 线程的优先级的改变有三种方式:用户指定优先级,根据进入等待状态的频繁程度提升或降低优先级,长时间得不到执行而提升优先级(饿死状态)。

  • 抢占(存在于可以抢占的线程中):线程在用尽时间片之后会被强制的剖夺继续执行的权力,进入就绪状态,这个过程叫做抢占。

  • 不可抢占的线程,线程主动放弃执行存在两种情况:第一,线程试图等待某事件。第二,线程主动放弃时间片。

  • 协程是用户态的轻量级的线程。

  • 写时复制:指的是两个任务可以同时自由的读取内存,但任意一个任务对内存进行修改时,内存就会复制一份提供给修改方使用,以免影响到其他的任务使用。

  • 同步:指在一个线程读取内存时,其他线程不得对这个内存进行读取。

  • 同步的最常见的方法是使用锁。下面就让我们介绍一下实现同步的一些方法:

  1. 二元信号量是一种最简单的锁,它有两种状态:占用和非占用。它适合只能有一个线程独占访问的资源。当一个线程读取内存时,二元信号量处于占有状态,当这个线程读取完内存时,由另一个线程释放这个二元信号量,以便这个信号量使用。

  2. 信号量是对二元信号量的一种扩展,它允许多个线程对内存进行访问。

  3. 互斥量和二元信号量很类似,当一个线程获得互斥量对内存数据进行限制,并读取完内存数据后,必须由这个线程对互斥量进行释放。

  4. 临界区是比互斥量是比更加严格的同步手段。当一个线程创建一个临界区时(也就是该线程获得临界区的锁时),该线程就会进入临界区。临界区的使用范围,只限于本线程。

  5. 读写锁致力于一种更加特定的场合的同步。对于读取频繁,而写入很少时,使用其他锁,效率会比较低,读写锁可以避免这个问题。

  6. 条件变量作为一种同步的手段,作用类似于一个栅栏。使用条件变量可以让许多线程一起等待某个事件,当事件发生时,所有的线程可以一起恢复执行。

  • 线程的并发(多个任务同时执行,cup对任务进行切换)是由多处理器或操作系统调度来实现的。

  • 用户使用的是用户级的线程,用户级的线程与内核级的线程并不是一一对应的。

  • 用户态多线程的实现方法: 一对一模型(一般使用API和系统调用的线程),多对一模型,多对多模型。

你可能感兴趣的:(程序员的自我修养——链接,装载与库)