进程与线程
1.由于多道程序环境,程序失去了封闭性(常考,另:还失去了顺序性),具有间断性和不可在现性特征。(还具有共享性和制约性),引入了进程。
2.进程是具有独立功能的程序在一个数据集合上运行的过程,—系统进行资源分配和调度的一个独立单位。
3.运行态➡️阻塞态:进程请求某一资源(如外设)的使用和分配或等待某一事件的发生(如I/O操作完成)时。
4.进程创建:
①为新进程分配一个唯一的进程标识号,并申请一个空白的PCB若申请失败,则创建失败。
②分配资源,为新进程的程序和数据及用户栈分配必要的内存空间,若资源不足,不是创建失败,而是处于阻塞态,等待内存资源。
③初始化PCB。
④插入就绪队列。
5.进程终止:
①根据被终止进程的标识符,检索PCB,读出状态
②若被终止进程处于执行状态,立即终止该进程的执行,将处理机资源分配给其他进程
③若还有子孙进程将其所有子孙进程终止
④将进程拥有的全部资源归还其父进程或归还操作系统
⑤将PCB从所在序列删除。
6.
引入进程:更好的使多道程序并发,提高资源利用率和系统吞吐量;
引入线程:减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能。
7.线程 进程区别:
①线程是独立调度的基本单位,进程是拥有资源的基本单位。
②线程有一点必不可少的资源,因为切换线程避免产生时空开销
8.用户进程被建立后,随着进程运行的正常或不正常结束而撤销。
9.进程中的线程共享进程内的全部资源,但进程中某线程的栈指针对其他线程是透明的,不能与其他线程共享。(线程实体有线程ID,程序计数器,寄存器集合和堆栈组成,ta唯有的必不可少的资源)
10.系统只有一个键盘,整个系统的键盘输入使用一个线程来处理。
11.进程与程序的关系:
①进程是程序的执行过程,程序是静态的指令集合。
②进程包含了程序,程序是进程的核心内容,没有程序就没有进程。
③进程与程序一对一:执行一条命令或运行一个应用程序时;
进程与程序一对多:一个进程执行过程中加载多个应用程序;
进程与程序多对一:以不同的参数或数据多次执行同一个应用程序时;
进程与程序多对多:并发执行不同的应用程序时。
调度(掌握的比较好,没有详细写)
12.时间片轮转是绝对可抢占的
实现临界区互斥的基本方法(掌握不好)
软件方法
单标志法
思想:采用公用变量(一个bool类型的值)用于指定是否允许进入临界区的进程编号。(turn = 0 🈯️p0进程进入临界区)
//P0: While(turn != 0); //进入区 critical section; //临界区 turn = 1; //退出区 remainder section; //剩余区 //P1: While(turn != 1); //进入区 *当turn为0时持续循环 直到时间片结束* critical section; //临界区 turn = 0; //退出区 remainder section; //剩余区
缺点:该方法必须交替进入临界区,违背“空闲让进”原则。
优点:保证了互斥。
双标志先检查
思想:在每个进程访问临界区资源前,先查看临界资源是否正在被访问,若正在被访问,该进程等待,否则,进程才进去临界区。
一个布尔类型数组flag,第i元素值表示i进程的状态。
flag[i] = false ➡️Pi未进入临界区。(pi不想进入临界区)
//Pi: While(flag[j]); //进入区 flag[i] = TRUE; *先检查后表达自己想使用* critical section; //临界区 flag[j] = FALSE; //退出区 remainder section; //剩余区 //Pj: While(flag[i]); //进入区 flag[j] = TRUE; critical section; //临界区 flag[j] = FALSE; //退出区 remainder section; //剩余区
缺点:并发操作时,此方法由于检查和修改操作不能一起执行导致pi,pj同时进入临界,违背“忙则等待”原则。
双标志后检查
思想:对于上面的双标志先检查进行优化,即将1⃣️2⃣️句颠倒。
先进行对自己的标志修改,后对进程进行检测。
先表达自己想用,后检查对方。
此方法由于两个进程均争抢进入临界区,发现对方也想进去临界区,进行谦让,导致“饥饿”现象。违背了“空闲让进”“有限等待”原则。
Peterson‘s Algorithm
对于上面两个无限等待的方法进行优化,增加变量turn,每个进程先设置自己的标志后设置turn标志。再对于另一个进程标志和不允许进入标志同时检测,保证一个进程进入临界区。
bool flag[2]; int turn = 0; //Pi: flag[i] = TRUE;turn = j; turn的值表达一个谦让于另一个进程的过程,愿意让j进程使用 While(flag[j] && turn == j); //进入区 *检查对方想进入并且自己谦让* critical section; //临界区 flag[j] = FALSE; //退出区 remainder section; //剩余区 //Pj: flag[j] = TRUE;turn = i; While(flag[i] && turn == i); //进入区 critical section; //临界区 flag[j] = FALSE; //退出区 remainder section; //剩余区
进入区:1.主动争取 2.主动谦让 3.检查对方是否想使用且自己最后表示了谦让动作
缺点:违背了“让权等待”原则,卡在wihle循环,占用cpu。
硬件方法中的硬件指令方法
中断屏蔽方法
优点:简单高效
缺点:::不适用于多处理机::;只适用于os内核进程,不适合将大权利给用户。
TSL指令
采用布尔型变量lock表示是否被加锁(true加锁,false未加锁
old记录临界区是否被上锁,无论是否上锁都设为上锁
bool TestAndSet(bool *lock) { bool old; old = *lock; //old用来存放lock原来的值 *lock = true; //将lock设为true return old; //返回原来的值 } While(TestAndSet(&lock)); //上锁并检查 临界区代码段 ; lock = false; //解锁 剩余区代码段;
B进程在将lock变为true时,A进程来,将一直停留在while循环,直至B进程退出时将lock修改为false,才能进入临界区。
缺点:违背了“让权等待”原则。
优点:实现简单,::适用于多处理机环境。::
Swap指令
逻辑同TSL指令
Swap(*a,*b) 函数; bool old = True; While(old == true) Swap(&lock,&old); 临界区代码 lock = false ; 剩余区代码段
优缺点同TSL指令。
死锁预防
破坏互斥条件
是一种合理性,但是不可行,os要保持互斥性(比如打印机🖨️
破坏不剥夺条件
长期请求新资源不能被满足,应释放自己的资源。
缺点:实现复杂;同时导致前一阶段失效;反复申请和释放资源增加系统开销,降低吞吐量;对于进程主动释放,可能造成饥饿现象。
适用于状态易于保护和恢复的
破坏请求并保持条件
一次申请完全部资源,才投入执行。
缺点:资源浪费(不使用时长期占用;导致“饥饿”现象(同前一个原因,别的进程长期占用,进程饥饿
破坏循环等待条件
(难懂!着重理解)
顺序资源分配法,对于资源进行编号,规定按资源递增顺序请求资源,同类资源一次申请完。
缺点:限制新类型设备增加(要重新分配编号;资源浪费