1、进程
进程是资源分配的基本单位。进程控制块(PCB)描述进程的基本信息的运行状态,所谓的创建进程和撤销进程,都是指对PCB的操作。
2、线程
线程是独立调度的基本单位。一个进程中可以有多个线程,它们共享进程资源。
3、进程与线程的区别
拥有的资源:进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问隶属进程的资源。
调度:线程是独立的单位,在同一进程中,线程的切换不会引起进程切换,从一个进程内的线程切换到另一个进程中的线程时,会引起进程切换。
系统开销:由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O设备等,所付出的开销远大于创建或撤销线程时的开销。进程切换时涉及到了当前执行的CPU环境的保护以及新调度的进程CPU环境的配置,而线程切换只需要保护和设置少量的寄存器的内容,开销很小。
通信:进程间通信(IPC)需要进程同步和进程互斥来辅助,以保证数据的一致性。而线程可以通过直接读/写同一进程中的数据段(如全局变量)来进行通信。
4、进程状态的切换:
就绪状态(ready):等待被调度
运行状态(running)
阻塞状态(waiting):等待资源
5、进程调度算法
1、批处理系统中的调度
1.1、先来先服务(FCFS):调度最先进入就绪队列的作业。
有利于长作业,但不利于短作业,因为短作业必须一直等待前面的长作业执行完毕才能执行,而长作业又需要执行很长时间,造成了短作业等待时间过长。
2.2、短作业优先(SJF):调度估计运行时间最短的作业。
长作业有可能会饿死,处于一直等待短作业执行完毕的状态。因为如果一直有短作业到来,那么长作业永远得不到调度。
2、交互式系统中的调度
2.1、优先级调度:除了可以手动赋予优先权之外,还可以把响应比作为优先权,这种调度方式叫做高响应比优先调度算法。
响应比 = (等待时间 + 要求服务时间) / 要求服务时间 = 响应时间 / 要求服务时间
这种调度算法主要是为了解决短作业优先调度算法长作业可能会饿死的问题,因为随着等待时间的增长,响应比也会越来越高。
2.2、时间片轮转:将所有就绪进程按 FCFS 的原则排成一个队列,每次调度时,把 CPU 时间分配给队首进程,该进程可以执行一个时间片。当时间片用完时,由计时器发出时钟中断,调度程序便停止该进程的执行,并将它送往就绪队列的末尾,同时继续把 CPU 时间分配给队首的进程。
时间片轮转算法的效率和时间片的大小有很大关系。因为进程切换都要保存进程的信息并且载入新进程的信息,如果时间片太小,会导致进程切换得太频繁,在进程切换上就会花过多时间。
6、进程同步:
1、临界区:对临界资源进行访问的那段代码称为临界区。
为了互斥访问临界资源,每个进程在进入临界区之前,需要先进行检查。
2、同步与互斥:
同步:多个进程按一定顺序执行;
互斥:多个进程在同一时刻只有一个进程能进入临界区。
3、信号量:信号量(Semaphore)是一个整型变量,可以对其执行 down 和 up 操作,也就是常见的 P 和 V 操作。
down:如果信号量大于 0 ,执行 -1 操作;如果信号量等于 0,进程睡眠,等待信号量大于 0;
up:对信号量执行 +1 操作,唤醒睡眠的进程让其完成 down 操作。
down 和 up 操作需要被设计成原语,不可分割,通常的做法是在执行这些操作的时候屏蔽中断;如果信号量的取值只能为 0 或者 1,那么就成为了 互斥量(Mutex) ,0 表示临界区已经加锁,1 表示临界区解锁。
4、管程:
使用信号量机制实现的生产者消费者问题需要客户端代码做很多控制,而管程把控制的代码独立出来,不仅不容易出错,也使得客户端代码调用更容易。
管程有一个重要特性:在一个时刻只能有一个进程使用管程。进程在无法继续执行的时候不能一直占用管程,否者其它进程永远不能使用管程。
管程引入了 条件变量 以及相关的操作:wait() 和 signal() 来实现同步操作。对条件变量执行 wait() 操作会导致调用进程阻塞,把管程让出来给另一个进程持有。signal() 操作用于唤醒被阻塞的进程。