操作系统一些基础知识
进、线程
- 进程(Process)是系统进行资源分配和调度的基本单位,线程(Thread)是 CPU 调度和分派的基本单位。
- 线程依赖于进程而存在,一个进程至少有一个线程。
- 进程有自己的独立地址空间,线程共享所属进程的地址空间。
- 进程是拥有系统资源的一个独立单位,而线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),和其他线程共享本进程的相关资源如内存、I/O、cpu等。
- 在进程切换时,涉及到整个当前进程CPU环境的保存环境的设置以及新被调度运行的CPU环境的设置,而线程切换只需保存和设置少量的寄存器的内容,并不涉及存储器管理方面的操作,可见,进程切换的开销远大于线程切换的开销。
- 线程之间的通信更方便,同一进程下的线程共享全局变量等数据,而进程之间的通信需要以进程间通信(IPC)的方式进行。
- 多线程程序只要有一个线程崩溃,整个程序就崩溃了,但多进程程序中一个进程崩溃并不会对其它进程造成影响,因为进程有自己的独立地址空间,因此多进程更加健壮。
什么是协程
协程是一种用户态的轻量级线程,协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。
协程多与线程进行比较
- 一个线程可以拥有多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。
- 线程进程都是同步机制,而协程则是异步。
- 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。
同一进程中的线程可以共享哪些数据
- 进程代码段。
- 进程的公有数据(全局变量、静态变量…)。
- 进程打开的文件描述符。
- 进程的当前目录。
- 信号处理器/信号处理函数:对收到的信号的处理方式。
- 进程 ID 与进程组 ID。
进程有哪几种状态
- 就绪状态:进程已获得除处理机以外的所需资源,等待分配处理机资源。
- 运行状态:占用处理机资源运行,处于此状态的进程数小于等于 CPU 数。
- 阻塞状态: 进程等待某种条件,在条件满足之前无法执行。
进程调度策略有哪些
- 先来先服务 first-come first-serverd(FCFS)。
- 按照请求的顺序进行调度。非抢占式,开销小,无饥饿问题,响应时间不确定(可能很慢);对短进程不利,对IO密集型进程不利。
- 最短作业优先 shortest job first(SJF)。
- 按估计运行时间最短的顺序进行调度。非抢占式,吞吐量高,开销可能较大,可能导致饥饿问题;对短进程提供好的响应时间,对长进程不利。
- 最短剩余时间优先 shortest remaining time next(SRTN)。
- 按剩余运行时间的顺序进行调度。(最短作业优先的抢占式版本)。吞吐量高,开销可能较大,提供好的响应时间;可能导致饥饿问题,对长进程不利。
- 最高响应比优先 Highest Response Ratio Next(HRRN)。
- 响应比 = 1+ 等待时间/处理时间。同时考虑了等待时间的长短和估计需要的执行时间长短,很好的平衡了长短进程。非抢占,吞吐量高,开销可能较大,提供好的响应时间,无饥饿问题。
线程独占哪些资源
- 线程 ID。
- 一组寄存器的值。
- 线程自身的栈(堆是共享的)。
- 错误返回码:线程可能会产生不同的错误返回码,一个线程的错误返回码不应该被其它线程修改。
- 信号掩码/信号屏蔽字(Signal mask):表示是否屏蔽/阻塞相应的信号(SIGKILL,SIGSTOP除外)。
并发、并行、异步的区别
- 并发:在一个时间段中同时有多个程序在运行,但其实任一时刻,只有一个程序在CPU上运行,宏观上的并发是通过不断的切换实现的。
- 多线程:并发运行的一段代码。是实现异步的手段。
- 并行(和串行相比):在多CPU系统中,多个程序无论宏观还是微观上都是同时执行的。
- 异步(和同步相比):同步是顺序执行,异步是在等待某个资源的时候继续做自己的事。
linux 系统进程类型
交互进程; 批处理进程; 监控进程(守护进程)。
通信方式(进程间)
- 管道(Pipe)。
- 命名管道。
- 消息队列。
- 信号(Signal)。
- 共享内存。
- 信号量(Semaphore):初始化操作、P 操作、V 操作;P 操作:信号量 -1,检测是否小于 0,小于则进程进入阻塞状态;V 操作:信号量 +1,若小于等于 0,则从队列中唤醒一个等待的进程进入就绪态。
- 套接字(Socket)。
死锁
- 在两个或者多个并发进程中,每个进程持有某种资源而又等待其它进程释放它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁(deadlock)。
- 原因:
- 竞争资源。
- 程序推进顺序不当。
- 必要条件:
- 互斥条件:一个资源一次只能被一个进程使用。
- 请求和保持条件:一个进程至少占有一个资源,并在等待另一个被其它进程占用的资源。
- 不剥夺条件:已经分配给一个进程的资源不能被强制性抢占,只能由进程完成任务之后自愿释放。
- 环路等待条件:若干进程之间形成一种头尾相接的环形等待资源关系,该环路中的每个进程都在等待下一个进程所占有的资源。
- 处理死锁基本方法:
- 预防死锁(摒弃除 1 以外的条件)。
- 避免死锁(银行家算法)。
- 检测死锁(资源分配图)。
- 解除死锁:
- 剥夺资源。
- 撤销进程。
互斥量、信号量
- 信号量:那是多线程同步用的,一个线程完成了某一个动作就通过信号告诉别的线程,别的线程再进行某些动作。
- 互斥量:这是多线程互斥用的,比如说,一个线程占用了某一个资源,那么别的线程就无法访问,知道这个线程离开,其他的线程才开始可以利用这个资源。
- 信号量与互斥量之间的区别:
- 互斥量用于线程的互斥,信号线用于线程的同步。这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。
- 互斥量值只能为 0/1,信号量值可以为非负整数。
- 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。
参考
- https://github.com/wolverinn/Waking-Up/blob/master/Operating%20Systems.md
未完待续…