基础
概念
- 周转时间:指从作业进入系统开始,直至其完成并退出系统为止所经历额时间- 分时系统:一台计算机分时提供给多个用户同时使用
- 硬实时任务:必须满足任务对截止时间的要求
- 软实时任务,不严格
windows是单用户多任务操作系统,linux是多用户多任务操作系统
- 操作系统的基本特征:并发、共享、虚拟、异步
- 并行是同一时刻发生,并发是在同一时间间隔内发生
- 进程是能独立运行并作为资源分配的基本单位
- 线程作为独立运行和独立调度的基本单位,基本上不拥有系统资源,所以调度开销小
- 进程的异步性:以不可预知的速度向前推进
- 调度包括作业调度(选择作业分配资源分别为它们建立进程),进程调度(选择进程分配CPU),中级调度(进程挂起解挂)
- 缓冲:解决CPU高速和I/O低速间的矛盾性
进程管理
- 进程实体:程序段、数据段、PCB
- PCB: 进程标识符、处理机状态、进程调度信息、进程控制信息
- 原语:若干条原子操作组成 ,原子操作是不可分割的基本单位,管态下执行,常驻内存
- 进程的创建:申请空白PCB,分配资源,初始化进程控制块,插入就绪队列
- 进程同步制约关系:1.间接制约关系(互斥,不知道对方是谁),2.直接制约关系(同步,知道对方的存在)
- 同步进制规则:空闲让进,忙则等待,有限等待,让权等待
- 信号量集:Swait(S,d1,d2); 需要不少于d1,减去d2个;Swait(S,1,1)和wait一样,Swait(S,1,0)是开关
- 管程:模块化,定义公共数据结构,如消息队列
- 高级进程通信机制:共享存储器系统(共享数据结构或者开辟内存区),消息传递系统,管道通信(1.互斥,2.同步,3.需要确定对方已存在)
- 消息传递通信的方法:1.直接通信方式,Send和Receive,2.间接通信方式,需要通过作为共享数据结构的实体,实体叫做信箱,信箱包括私用(用户创建),公用信箱(os创建),共享信箱(进程创建,指定共享进程的名称)
处理机调度和死锁
- 带权周转时间:周转时间与系统为它提供服务的时间之比
- 调度算法:先来先服务FCFS,短作业有限SJF,高优先权调度算法,高响应比优先调度,优先权为周转时间与要求服务时间的比值,时间片轮转调度
- 产生死锁的原因:竞争资源,进程间推进顺序不合理
- 死锁必要条件:互斥,请求和保持,不剥夺,环路等待
- 解决死锁:银行家算法
- 预防死锁:摒弃请求和保持,摒弃不剥夺,摒弃环路等待
- 程序的装入和链接:绝对装入,可重定位装入,动态运行时装入;静态链接,装入时动态链接,运行时动态链接
- 连续分配方式:单一连续分配,固定分区分配,动态分区分配
- 分区分配算法:首次适应算法(从首部开始找),循环首次适应算法(从开始找),最佳适应算法,最坏适应算法,快速适应算法
- 页面置换算法:最佳置换算法(选择未来最长时间不再访问的),最近最久未使用LRU(选择以前未访问时间最长的)
线程间的通信方式
锁机制:包括互斥锁、条件变量、读写锁
互斥锁提供了以排他方式防止数据结构被并发修改的方法。
读写锁允许多个线程同时读共享数据,而对写操作是互斥的。
条件变量可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。 信号量机制(Semaphore):包括无名线程信号量和命名线程信号量
信号机制(Signal):类似进程间的信号处理
线程间的通信目的主要是用于线程同步,所以线程没有像进程通信中的用于数据交换的通信机制。
PCB结构
进程实体:程序段、数据段、PCB
PCB: 进程标识符、处理机状态、进程调度信息、进程控制信息
但pcb还有一些复杂的
- 进程调度信息: 优先级
- 进程通信:与信号量相关的等待队列
- 进程链接:父子进程
- 时间和定时器:进程创建时间,时间片上剩余时间
- 文件系统信息:进程可以打开或关闭文件,文件属于系统资源,Linux 内核要对进程使用文件的情况进行记录
- 虚拟内存信息: 除了内核线程(Kernel Thread),每个进程都拥有自己的地址空间(也叫虚拟空间)
- 面管理信息: 当物理内存不足时,Linux 内存管理子系统需要把内存中的部分页面交换到外存,其交换是以页为单位的。
QA
用户态和内核态是如何切换的?
当应用程序执行系统调用时,CPU 将从用户态切换到内核态,进入内核空间执行相应的内核代码,然后再切换回用户态。
进程和线程的联系和区别?
进程是一个正在执行的程序实例。每个进程都有自己独立的地址空间、全局变量、堆栈、和文件描述符等资源。
线程是进程中的一个执行单元。一个进程可以包含多个线程,它们共享进程的地址空间和资源。
线程上下文切换了解吗?
这还得看线程是不是属于同⼀个进程:
- 当两个线程不是属于同⼀个进程,则切换的过程就跟进程上下⽂切换⼀样;
- 当两个线程是属于同⼀个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据;
所以,线程的上下⽂切换相⽐进程,开销要⼩很多。
活锁和饥饿锁了解吗?
饥饿锁:
饥饿锁,这个饥饿指的是资源饥饿,某个线程一直等不到它所需要的资源,从而无法向前推进,就像一个人因为饥饿无法成长。
活锁:
在活锁状态下,处于活锁线程组里的线程状态可以改变,但是整个活锁组的线程无法推进。
活锁可以用两个人过一条很窄的小桥来比喻:为了让对方先过,两个人都往旁边让,但两个人总是让到同一边。这样,虽然两个人的状态一直在变化,但却都无法往前推进。
什么是快表?
同样利用了局部性原理,即在⼀段时间内,整个程序的执⾏仅限于程序中的某⼀部分。相应地,执⾏所访问的存储空间也局限于某个内存区域。
利⽤这⼀特性,把最常访问的⼏个⻚表项存储到访问速度更快的硬件,于是计算机科学家们,就在 CPU 芯⽚中,加⼊了⼀个专⻔存放程序最常访问的⻚表项的 Cache,这个 Cache 就是 TLB(Translation Lookaside Buffer) ,通常称为⻚表缓存、转址旁路缓存、快表等。
什么是缺页中断?
缺页中断(Page Fault)是虚拟内存管理的一个重要概念。当一个程序访问的页(页面)不在物理内存中时,就会发生缺页中断。操作系统需要从磁盘上的交换区(或页面文件)中将缺失的页调入内存。
零拷贝了解吗?
假如需要文件传输,使用传统 I/O,数据读取和写入是用户空间到内核空间来回赋值,而内核空间的数据是通过操作系统的 I/O 接口从磁盘读取或者写入,这期间发生了多次用户态和内核态的上下文切换,以及多次数据拷贝。

目的就是把磁盘文件数据 写到socket缓冲区里。
实现方式
- mmap + write
mmap() 系统调⽤函数会直接把内核缓冲区⾥的数据「映射」到⽤户空间,这样,操作系统内核与⽤户空间就不需要再进⾏任何的数据拷⻉操作。
- sendfile 新的方式
在 Linux 内核版本 2.1 中,提供了⼀个专⻔发送⽂件的系统调⽤函数 sendfile() 。
⾸先,它可以替代前⾯的 read() 和 write() 这两个系统调⽤,这样就可以减少⼀次系统调⽤,也就减少了 2 次上下⽂切换的开销。
其次,该系统调⽤,可以直接把内核缓冲区⾥的数据拷⻉到 socket 缓冲区⾥,不再拷⻉到⽤户态,这样就只有 2 次上下⽂切换,和 3 次数据拷⻉。
linux进程SIGCHLD信号
当一个子进程改变了它的状态时(停止运行,继续运行或者退出),有两件事会发生在父进程中:
- 得到 SIGCHLD 信号;
- waitpid() 或者 wait() 调用会返回。
其中子进程发送的 SIGCHLD 信号包含了子进程的信息,比如进程 ID、进程状态、进程使用 CPU 的时间等。
在子进程退出时,它的进程描述符不会立即释放,这是为了让父进程得到子进程信息,父进程通过 wait() 和 waitpid() 来获得一个已经退出的子进程的信息。
孤儿进程
一个父进程退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。
孤儿进程将被 init 进程(进程号为 1)所收养,并由 init 进程对它们完成状态收集工作。
由于孤儿进程会被 init 进程收养,所以孤儿进程不会对系统造成危害。
僵尸进程
一个子进程的进程描述符在子进程退出时不会释放,只有当父进程通过 wait() 或 waitpid() 获取了子进程信息后才会释放。如果子进程退出,而父进程并没有调用 wait() 或 waitpid(),那么子进程的进程描述符仍然保存在系统中,这种进程称之为僵尸进程。
僵尸进程通过 ps 命令显示出来的状态为 Z(zombie)。
系统所能使用的进程号是有限的,如果产生大量僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程。
要消灭系统中大量的僵尸进程,只需要将其父进程杀死,此时僵尸进程就会变成孤儿进程,从而被 init 进程所收养,这样 init 进程就会释放所有的僵尸进程所占有的资源,从而结束僵尸进程。
中断分类
1. 外中断
由 CPU 执行指令以外的事件引起,如 I/O 完成中断,表示设备输入/输出处理已经完成,处理器能够发送下一个输入/输出请求。此外还有时钟中断、控制台中断等。
2. 异常
由 CPU 执行指令的内部事件引起,如非法操作码、地址越界、算术溢出等。
3. 陷入
在用户程序中使用系统调用。