1、进程与线程
进程:
- 父进程先创建,子进程后创建,但是子进程先死亡,因为子进程可能需要共享父进程的资源;
- 进程中止原因:进程结束、进程终止、内存清除;
- 生产者-消费者:生产者进程是产生数据的进程,在硬盘中读取数据到内存;中间线程将缓冲区1的数据解压到缓冲区2;消费者进程是消费数据的进程,将缓冲区2将数据显示;
- 生产者消费者一定是时间片轮转,不是批处理,否则会陷入无尽的等待;
- 原语:执行过程中不可中断,一条机器指令是一条原语,事务的原子性;
- 阻塞会等待,非阻塞不会等待;
- 缓冲区:节省时间,提高效率;
- 进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会创建一个进程,并为它分配资源,然后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
线程:
- 线程:一个进程可以包括一个至多个线程(有限个),每个线程拥有自己的计存器和堆栈,共享进程的数据和文件;
- 三个主要的线程库:POSIX Pthreads、Win32 threads、Java threads;
- c语言API,操作系统系统调用,API在系统调用之上,API调用系统调用,系统调用与操作系统有关,API跨系统,更高层可移植性,接口比系统调用更简单;
- Java在语言层可以创建线程,c语言不行,java虚拟机把java语言解析成字节码,java中ready状态和running状态合并为runnable状态;
- 用户级线程多于内核级线程,不存在一个用户线程对应多个内核线程;
- 线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。
2、CPU调度
- 用户进程执行I/O操作需要执行系统调用,进程处于等待状态只是等待CPU,可照样执行I/O操作;
- 进程因为时间片到了,从运行状态转到就绪状态,如果就绪队列为空,进程依旧会回到就绪队列;
- 优化:最大化CPU利用率与吞吐量,最小化周转时间、等待时间和响应时间;
- 程序从磁盘调入内存就是进程,不在内存只能叫做程序;
- 进程调度分为剥夺式(会中断正在执行的进程)和非剥夺式;
- CPU调度四种情形:进程从运行到等待、从运行到就绪、从等待到就绪、终止;
- 优先级调度:每个进程带有一个优先级数字,小的数字优先级越高;
- 操作系统进程优先级比用户进程优先级高,操作系统负责调度,否则用户进程得不到调度;
- 优先级调度问题:静态优先级会导致饥饿问题,低优先级的进程可能永远得不到调度,于是将进程等待时间加入进程的优先级,称为动态优先级,但是动态优先级会增加额外的开销;
- 现代操作系统的操作策略:先到先服务,优先级调度和时间片轮转的共同作用;
- 时间片轮转:每个进程会活得一定时间的时间片,通常10-100毫秒,时间片结束,进程进入就绪队列;
- 时间片长,上下文切换的时间少,CPU利用率高;
3、死锁
- 一系列阻塞的进程,互相持有资源,又等待对方释放资源,就形成了死锁;
- 硬件资源:cpu、内存、I/O设备;软件资源:进程、数据等;
- 资源的使用:请求->用->释放;
- 死锁四种情形:互斥,持有和等待,非剥夺,循环等待;
- 解决方法:每个进程申请最大资源数(小于操作系统所有的),操作系统要么分配所有资源,要么不分配;
- 银行家算法:银行家算法是从当前状态出发,按照系统各类资源剩余量逐个检查各进程需要申请的资源量,找到一个各类资源申请量均小于等于系统剩余资源量的进程P1。然后分配给该P1进程所请求的资源,假定P1完成工作后归还其占有的所有资源,更新系统剩余资源状态并且移除进程列表中的P1,进而检查下一个能完成工作的客户,…。如果所有客户都能完成工作,则找到一个安全序列,银行家才是安全的。若找不到这样的安全序列,则当前状态不安全;