1. 什么是操作系统
- 操作系统(Operating System,OS)是管理计算机硬件和软件资源的程序,是计算机系统的内核与基石。
- 操作系统本质上是运行在计算机上的软件程序。
- 操作系统为用户提供了一个与系统交互的操作界面。
- 操作系统分为内核与外壳(我们可以把外壳理解成围绕着内核的应用程序,而内核就是能操作硬件的程序)。
补充:内核负责管理系统的进程、内存、设备驱动程序、文件和网络系统等等,决定着系统的性能和稳定性,是连接应用程序和硬件的桥梁。内核就是操作系统背后黑盒的核心。
2. 系统调用
2.1 用户空间和内核空间
用户空间和内核空间都属于虚拟空间。现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操作系统将虚拟空间划分为两部分,一部分为内核空间,一部分为用户空间。
针对 Linux 操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0×00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。
我们运行的程序基本都是运行在用户态,如果我们调用操作系统提供的系统态级别的子功能时就需要系统调用了。
2.2 什么是系统调用?
我们运行的程序基本都运行在用户态,当我们需要调用操作系统提供的内核态级别的子功能时,就需要系统调用了。也就是说在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。
这些系统调用按功能大致可分为如下几类:
- 设备管理。完成设备的请求或释放,以及设备启动等功能。
- 文件管理。完成文件的读、写、创建及删除等功能。
- 进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
- 进程通信。完成进程之间的消息传递或信号传递等功能。
- 内存管理。完成内存的分配、回收以及获取作业占用内存区大小及地址等功能。
3. 死锁
3.1 什么是死锁
当两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,就称为死锁。3.2 产生死锁的必要条件
产生死锁需要同时满足下面四个条件:
- 互斥条件:该资源任意一个时刻只由一个线程占有。
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。进程至少已经占有一个资源,但又申请新的资源;由于该资源已被另外进程占有,此时该进程阻塞;但是,它在等待新资源之时,仍继续占用已占有的资源。
- 不剥夺条件:线程已获得的资源在未使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。
循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
3.3 预防死锁
如果想要预防死锁,破坏这四个条件的其中一个就好了。
破坏请求条件:一次性分配所有资源,这样就不会再有请求了。
- 破坏保持条件:只要有一个资源得不到分配,也不给这个进程分配其他的资源。
- 破坏不剥夺条件:当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源。
- 破坏循环等待条件:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反。
3.4 避免死锁
避免死锁同样是属于事先预防的策略,但并不是事先采取某种限制措施破坏死锁的必要条件,而是在资源动态分配过程中,防止系统进入不安全状态,以避免发生死锁。这种方法所施加的限制条件较弱,可以获得较好的系统性能。3.4.1 银行家算法
银行家算法是最著名的死锁避免算法,它的思想是把操作系统看作银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。
操作系统按照银行家制定的规则为进程分配资源。
- 当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
- 当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请资源数之和是否超过了该进程对资源的最大需求量。若超过则拒绝分配资源,若没超过则再测试系统现存的资源能否满足该进程需要的最大资源量,若满足则按当前的申请量分配资源,否则也要推迟分配。
3.4.2 安全序列
是指系统能按某种进程推进顺序(P1, P2, P3, …, Pn),为每个进程 Pi 分配其所需要的资源,直至满足每个进程对资源的最大需求,使每个进程都可以顺序地完成。这种推进顺序就叫安全序列。银行家算法的核心就是找到一个安全序列。
3.4.3 系统安全状态
如果系统能找到一个安全序列,就称系统处于安全状态,否则,就称系统处于不安全状态。
3.5 死锁解除
- 资源剥夺法:挂起某些死锁进程,并抢占它的资源,将这些资源分配给其他死锁进程(但应该防止被挂起的进程长时间得不到资源)。
- 撤销进程法:强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源(撤销的原则可以按进程优先级和撤销进程代价的高低进行)。
- 进程回退法:让一个或多个进程回退到足以避免死锁的地步。进程回退时自愿释放资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点。
4. 孤儿进程和僵尸进程
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被 init 进程(进程号为1)所收养,并由 init 进程对它们完成状态收集工作。
僵尸进程:一个进程使用 fork 创建子进程,如果子进程退出,而父进程并没有调用 wait 或 waitpid 获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。
5. 文件描述符
文件描述符(File descriptor) 是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。
文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。
6. top 命令详解
- 第一行:系统当前时间,系统已运行时间,当前登陆系统的用户,1分钟、5分钟、15分钟的负载情况。
- 第二行:进程数,一个运行中,289个休眠中,0个处于 stoped 状态,0个处于 zombie(僵尸状态)。
- 第三行:CPU 状态:us是用户空间占用CPU的百分比,sy是内核空间占用CPU的百分比,ni是改变过优先级的进程占用CPU的百分比,id是空闲CPU百分比,wa是IO等待占用CPU的百分比,hi是硬中断占用CPU的百分比,si是软中断占用CPU的百分比。
- 第四行:内存状态。
第五行:swap 交换分区。
PID:进程ID
- USER:进程所有者
- PR:进程优先级
- NI:nice值,负值表示高优先级,正值表示低优先级
- VIRT:进程使用的虚拟内存总量
- RES:进程使用的未被换出的物理内存大小
- SHR:共享内存大小
- S:进程状态 D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
- %CPU — 上次更新到现在的CPU时间占用百分比
- %MEM — 进程使用的物理内存百分比
- TIME+ — 进程使用的CPU时间总计,单位1/100秒
- COMMAND — 进程名称(命令名/命令行)
7. 局部性原理
局部性原理表现在以下两个方面:
- 时间局部性:如果程序中的某条指令一旦执行,不久以后该指令可能再次执行;如果某数据被访问过,不久以后该数据可能再次被访问。产生时间局部性的典型原因,是由于在程序中存在着大量的循环操作。
- 空间局部性:一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定的范围之内,这是因为指令通常是顺序存放、顺序执行的,数据也一般是以向量、数组、表等形式簇聚存储的。
时间局部性是通过将近来使用的指令和数据保存到高速缓存存储器中,并使用高速缓存的层次结构实现。空间局部性通常是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。虚拟内存技术实际上就是建立了 “内存一外存”的两级存储器的结构,利用局部性原理实现髙速缓存。