深入理解计算机系统 书笔记

深入理解计算机系统

计算机系统漫游

信息就是位+上下文

​ 系统中所有的信息-包括磁盘文件,内存中的程序,内存中存放的用户数据以及网络上传送的数据,都是由比特标识。

程序被其他程序翻译成不同的格式

​ 在Unix系统中,从源文件到目标文件的转化是由编译器驱动程序完成的,有四个阶段:预处理器,编译器,汇编器,链接器。

​ 理解链接时出现错误:一些最麻烦的问题往往与链接器操作有关,尤其当试图构建一个大型软件系统,如:链接器报告说无法解析一个引用,静态变量和全局变量的区别。

处理器读并解释储存在内存的指令

系统硬件组成

​ 总线:携带信息字节并负责在各个部件间传递;I/O设备:每个I/O设备通过一个控制或适配器与I/O总线相连;主存:主存是一个临时存储,在处理器执行程序时,用于存放程序和程序处理数据;处理器:负责解释或执行存储在主存中指令的引擎。

操作系统管理硬件

在这里插入图片描述

在这里插入图片描述

​ 操作系统有两个基本功能:防止硬件被失控的应用程序滥用;向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备。

进程

​ 进程是操作系统对一个正在运行的程序的一种抽象,在一个系统中可以同时运行多个进程,而每个进程都好像在独占使用硬件,并发运行,是说一个进程的指令和另一个进程的指令是交错执行的。

​ 操作系统保持跟踪进程运行所需的所有状态信息,这种状态就是上下文,包括许多信息,如PC和寄存器文件的当前值,以及主存的内容。当操作系统决定要把控制权从当前进程转移到某个新进程时,就会进行上下文切换,即保持当前进程的上下文,恢复新进程的上下文,转移控制权,从上次停止的地方开始。

​ 下图展示了hell进程运行时,图中有两个进程一个是shell进程,一个是hello进程,shell进程在运行,等待命令行的输入。当让它运行hello程序时,就会通过调用专门的函数,即系统调用,来执行程序。

在这里插入图片描述

​ 从一个进程到另一个进程是由操作系统内核管理的,内核是操作系统常驻主存部分。当应用程序需要操作系统的某些操作时,比如读写文件,应用程序会执行一条特殊的系统调用,将控制权转交给内核。

线程

​ 一个进程实际上由多个线程组成,每个线程都运行在进程的上下文中,并共享同样的代码和全局数据。由于网络服务器中对并行处理的需求,线程成为重要的编程模型,因为多线程之间比多进程之间更容易共享数据。

虚拟内存

​ 虚拟内存是一个抽象概念,为每个进程提供了一个假象,即每个进程都独占的使用内存,每个进程看到的内存都是一致的。

在这里插入图片描述

​ 程序代码和数据:对于所有进程,代码是从同一固定地址开始,紧接着是和全局变量相对应得数据位置。

​ 堆:代码和数据后紧随者的是运行堆,代码和数据区的大小是指定了,但是堆的大小是可动态变化的;

​ 共享库:大约在地址空间的中间部分是一块用来存放像C标准库这样的共享库的代码和数据的区域。

​ 栈:位于用户虚拟地址顶部的是用户栈,编译器用它来实现函数调用。

​ 内核虚拟内存:地址空间的顶部是为内核保留的。不允许程序读写和直接调用内核代码定义的函数。

异常控制流(Exceptional Control Flow,ECF)

​ 在操作系统层中,内核通过上下文切换将控制从一个用户进程转移到另一个用户进程。在应用层,一个进程可以发送信号到另一个进程,接收者会将控制突然转移到它的一个信号处理程序。一个程序可以通过回避通常的栈规则,并执行其他函数中任意位置的非本地跳转来对错误做出反应。

异常

​ 异常是异常控制流的一种形式,一部分由硬件实现,一部分由操作系统实现。异常是控制流中的突变,用来响应处理器中的某些变化

在这里插入图片描述

​ 状态变化称为事件,事件可能和当前指令的执行直接相关,如发生虚拟内存缺页,也可能和当前指令无关,如一个系统定时器产生信号或者一个I/O请求。

​ 在任何情况下,处理器发现异常后,会通过异常表,调用对应的操作系统子程序(异常处理程序)。

​ 异常类别有中断,陷阱,故障和终止。

在这里插入图片描述

中断

​ 中断是异步发生的,是来自外部的I/O设备的信号的结果。硬件中断不是由指令产生的,硬件中断的处理程序一般称为中断处理程序。

陷阱和系统调用

​ 陷阱是有意的异常,陷阱处理程序将控制返回到下一条指令。陷阱最重要的用途是在用户程序和内核之间提供一个像过程一样的接口,叫做系统调用。

​ 用户程序通常需要向内核请求服务,如读取文件,创建新进程;为了允许对这些内核服务的受控访问,处理器提供了一条特殊的“syscall n”指令,当用户程序需要请求服务,就调用这条指令。

​ 系统调用和普通的程序调用是一样的,但是实现方式不同,普通程序调用是运行在用户模式的,系统调用是内核模式。

故障

​ 故障是由于错误情况引起的,可能被故障处理程序修复,如果修复不成功就这些abort程序,abort会终止引起故障的应用程序。

上下文切换

​ 操作系统内核使用一种称为上下文切换的较高层形式的异常控制流来实现多任务。上下文切换机制是建立在那些较低层的异常机制上的。

​ 内核为每个进程维持一个上下文,上下文是内核重启一个被抢占进程所需的状态,由进程的信息组成。在进程执行过程中,内核可以随时决定抢占该进程,回复以前被抢占进程,这个过程称为调度。在内核调度一个新的进程运行后,使用上下文切换的机制进行控制转移,1)保持当前进程的上下文,2)恢复某个先前被抢占的进程被保存的上下文,3)将控制传递给这个新回复进程。

​ 下图是一个上下文切换的过程

在这里插入图片描述

进程控制

​ 每个进程都有一个唯一的正数进程ID(PID),

创建和终止进程

​ 可以认为进程总是处于运行,停止(进程的执行被挂起,且不会被调度)和终止这三个状态中的一个。

​ 父进程通过调用fork函数创建一个新的运行子进程。新创建的子进程几乎但不完全与父进程相同,子进程得到与父进程虚拟地址空间相同的一份副本,子进程还可以读取父进程打开的任何文件,唯一不同的是它们有不同的PID。

​ fork函数比较奇怪的一个点:只被调用一次,却返回两次,一次是在父进程中,一次是在新创建的子进程中;在父进程中,fork返回的是子进程的PID,在子进程,fork返回的是0。因为子进程的PID总是为非零,fork函数的返回结果,可以分辨出真正的子进程。

​ 子进程和父进程是并发运行的独立进程,不能对不同进程中指令的交换执行做任何假设,必须考虑所有情况。

回收子进程

​ 当一个进程由于某种原因终止了,内核并不是立即把它从系统中移出去。相反,进程被保存在一种已终止的状态中,直到被它的父进程回收。当父进程回收了已终止的子进程,内核就把子进程的退出状态传递给父进程,然后抛弃掉已终止的子进程,现在开始,这个进程不再存在。一个终止了但未被回收的进程称为僵死进程。

​ 如果父进程终止了,内核会安排init进程称为它的孤儿进程的养父。init进程的PID为,是系统启动时在内核创建的,不会终止,是所有进程的祖先。如果父进程没有回收它的僵死进程,内核会安排init进程去回收它们。

信号

​ 信号是更高层的一次,允许进程和内核中断其他进程。信号通知进程系统中发生一个某种类型的事件。

​ 传送信号到目的进程是由两个不同步骤组成的:发送信号:内核通过更新目的进程上下文中的某个状态,发送一个信号给目的进程;接收信号:当目的进程被内核强迫以某种方式对信号的发送做出反应,就是接收了信号。

​ 一个发出而没有被接收的信号叫做待处理信号。在任何时刻,一种类型最多只会有一个等待信号,如果一个进程有一个待处理的类型为k的信号,那么接下来接收到类型为k的信号会被丢弃。

发送信号

​ Unix系统提供了大量向进程发送信息的机制,这些机制都是基于进程组的。每个进程只属于一个进程组,进程组是由一个正整数进程组PGID标识的。

​ 在任何时刻,至多只有一个前台作业和0个或多个后台作业。在键盘输入CTRL+C会导致内核发送一个SIGINT信号到前台进程组中的每个进程,默认情况下,结果是终止前台作业,类似地,输入Ctrl+Z会发送一个SIGTSTP信号到前台进程组的每个进程,默认是停止前台作业。

​ 在任何时刻,至多只有一个前台作业和0个或多个后台作业。在键盘输入CTRL+C会导致内核发送一个SIGINT信号到前台进程组中的每个进程,默认情况下,结果是终止前台作业,类似地,输入Ctrl+Z会发送一个SIGTSTP信号到前台进程组的每个进程,默认是停止前台作业。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值