OS1_进程与线程的管理

序言

1.OS以进程、线程的方式在CPU中执行静态保存在外存(内存)中的程序,进程的构成与状态转化,特别是进程的切换;
2.当有多个进程处于就绪态,有哪些常见的挑选以执行方式;
3.并发执行(乱序发射)的进程,共享内存等资源,很可能修改其他程序的变量,需作同步处理来控制;
此外有些资源如打印机不能共享,需作互斥处理;

Question

  1. 程序分割成线程执行的代码怎么写?用进程管理程序实现,python如何可以实现多线程并行吗,如何实现?
  2. 为什么用户级线程中,1个线程因系统调用被阻塞会导致其他线程也被阻塞?

因为在大多数操作系统中,内核是单线程运行的,所以当一个线程被阻塞时,它会释放CPU资源。这将导致其他线程在等待CPU资源时也被阻塞,其他线程只能要么等待,无法保存现场(工作在用户层)再切换,produce block。
在内核级线程中,中断的保存/恢复现场为内核的功能,可以实现线程间的调度,且支持多处理机。
在组合方式中,
a. 用户进程的多个线程对应内核级的多个线程,用户1个线程系统调用的内核级线程A被阻塞,CPU可以切换到其他线程的不同内核级线程B;
b. 多核处理器可对应多个内核级线程;

  1. 系统动态DLL库是个玩意?

进程

  • 进程是一段指令流,还是?process=PCB+data section+code section
    PCB=处理器(时间片轮转比其他设备周期短,单成1列)+其他资源+进程控制与管理信息+PIDUUID
  • 不同的进程是如何利用系统资源(IO,MM,CPU)的?
  • 进程之间如何通信?进程如何运转?

线程

  • 线程是处理器调度与分配的基本单元
  • 进程是除了处理器之外其他资源的分配单位——IO,MM的分配单元

进程调度

  • 线程的调度类似,不过同一个进程的线程切换不用替换进程上下文,运行时间的算法需要更新(更复杂了)

同步与互斥

同步与互斥都围绕共享资源的使用:
1.对于那些只能被单独访问的共享资源,要做互斥处理;
2.对于那些可以被共享访问的资源,虽然RAR没问题,但RAW,WAR,WAW 均可能导致最终的共享资源结果不同,要作同步处理。
互斥可通过用户程序中使用API实现lock和release

  1. 数据库中,为了防止数据的脏读,需要给数据表或表项加上二阶段锁或S锁,
  2. 为什么要引入同步与互斥?——进程之间共享资源,不同进程并发执行,封闭性丧失,为了得到逻辑正确的结果。
  3. 临界资源:一次只能被1个进程访问的资源
  4. 临界区:访问临界资源的代码;
  5. 进入区:访问临界资源前,要把临界区的标志设置为正在访问;
  6. 退出区:将正在访问的临界区的signal清除;
  7. 剩余区:代码中的其余部分?
  8. 同步:如A和B通过缓冲区实现数据传送,缓冲区满了,A必须等待B读取数据,才能接着传送;缓冲区空,B必须等待A传入数据,才能接着传送;缓冲区相比于机制,再与缓冲区大小固定。
  9. 互斥:对临界资源的访问;而同步,是为了正确完成任务而协调工作次序;

双标志互斥alg的问题是进程的线程乱序执行导致的,只有Peterson alg能在所有乱序执行保证同步的3大准则:
空则让进,忙则等待,有限等待,(让权等待)。

硬件实现有中断屏蔽和硬件指令2种方法:

  1. 中断屏蔽:关中断,临界区,开中断。
  2. 硬件指令方法:TestandSet或Swap原子操作
boolean TestandSet(boolean *lock){
	boolean old;
	old=*lock;
	*lock=true;
	return old;;
}
while TestandSet(&lock);
临界区
lock=false;
剩余区

comment:

  1. 为每个临界资源设置一个共享布尔变量
  2. 和下面的Swap都是互斥锁
Swap(boolean *a,boolean *b){
	boolean temp;
	temp=*a;
	*a=*b;
	*b=temp;
}
key=true;
while(key!=false)
	swap(&key,&lock);
临界区
lock=false
剩余代码

comment:

  1. 当lock=false(代表资源空闲),设置key=false,lock=ture,标识该进程独占临界资源;
  2. swap和testandset其实是硬件原子操作,不可分,不会出现多个进程进入lock=false的swap函数,不会出现共用临界资源;
  3. 当lock=true,未得到临界资源的进程会一直while查询,占用处理机资源,不能实现让权等待;

对比

实现临界区互斥的硬件方法和软件方法各有什么优势?

硬件方法的优势:
原子性操作:硬件方法通常使用特定的指令或硬件机制来实现原子操作,如原子交换(Atomic Exchange)或测试并设置(Test-and-Set)。这些操作在硬件级别上保证了操作的原子性(不会出现共用临界资源),无需额外的软件开销。
性能:硬件方法通常比软件方法更高效,因为它们直接利用了硬件的特性,如高速缓存和并行处理能力。这使得硬件方法更适合于对性能要求较高的应用场景。

软件方法的优势:
可移植性:软件方法不依赖于特定的硬件指令或机制,因此更易于在不同的平台上实现和移植。这使得软件方法更具通用性,可以应用于不同类型的系统和架构。
灵活性:软件方法通常可以更灵活地实现复杂的同步机制,如信号量、条件变量等。这些机制提供了更多的控制和功能,可以满足不同线程同步需求。
容错性:软件方法可以在一些特殊情况下提供更好的容错性。例如,当硬件出现故障或不支持某些原子操作时,软件方法可以通过算法和复杂的同步机制来弥补。

需要注意的是,硬件方法和软件方法并不是互斥的选择,它们可以结合使用来提供更可靠和高效的同步机制。例如,硬件指令可以用于实现基本的原子操作,而软件方法可以用于构建更复杂的同步机制。选择何种方法取决于具体的应用需求、平台特性和性能要求。

解决临界区——互斥锁+信号量

互斥锁更easy

acquire(){
	//锁被占用则等待
	while(available!=true)
		;	
	//锁空闲,占用后,将锁设为false
	available=false}
release(){	//释放锁
	available=true}

信号量(系统中的资源数目)mechanism

采用两个不可中断(软件中由屏蔽中断方法实现)的原语——wait和signal来管理

整形信号量

wait(S){	//请求资源
	while(S<=0)//若没有资源,则等待
	S--;		//占用资源,S--
}
signal(S){
	S++;	//释放资源
}

Defect:wait在无资源可用,会一直occupy cpu——while query,违背 让权等待

记录型信号量

  • S.value>0,表示可用的资源数目;
  • S.value<=0,标识阻塞的进程数目;
  • 每种资源对应1个S
typedef struct{
	int value;
	struct process *L;
} semaphore(信号量);

请求资源

void wait(semaphore S){
	S.value--;	//S>0则资源数--;S<0则阻塞进程数++;
	if(S.value<0){	
		add this process to S.L;
		block(S.L);
	}
}

释放资源

voic signal(semaphore S){
	S.value++;	//资源数++或阻塞进程数--
	if(S.value<0){	//若为后者,唤醒该进程——资源来临
		remove process P from S.L;
		wakeup(P);
	}
}

信号量的饮用

只有互斥用到了临界资源;
同步和前驱只关于特定变量的逻辑序;

同步
——进程按照(资源的)特定顺序执行

semaphore S=0;
P1(){
	x;
	V(S);
	...
}
P2(){
	...
	P(S);
	y;
	...
}

互斥——只有1个进程能进入临界区

  • P(S)请求资源;V(S)释放资源
semaphore S=1;
P1(){
	...
	P(S);
	critical area;
	V(S);
}
P2(){
	...
	P(S);
	critical area;
	V(S);
}

用同步实现前驱关系——每个偏序关系用1个资源

S1(){
	V(a1);
}
S2(){
	P(a1);
	V(b1);V(b2);
}

分析同步、互斥、前驱关系,设置信号量,确定P,V

管程

背景:针对每个共享变量,所有使用变量都要设置P(),V()操作;
改进:每个共享资源,只要1个共享数据结构demo来管理;

管程=类,成员变量为共享资源的数目,成员函数为对共享资源的操作,如对互斥变量的take_away和release,

多个共享资源可以用记录型信号量表示,

不知道为什么要把条件变量单独拎出来,用来表示进程被阻塞的原因,

  • 如果两个进程有先后关系,它们之间可以一个条件变量的lock和release,
  • 互斥资源可以且应该用条件变量表示,就是整数型信号量

互斥问题的求解

  • 互斥资源的访问用锁表示,
  • 像生产者、消费者问题,明明可以用num表示缓冲区的数目,为了符合P(锁),V(释放)的形式(值得唾弃),
    用full和empty两个信号量,并用mutex实现对full和empty的互斥修改(simultaneously 只有一个生产者/消费这个能访问缓冲区)——然鹅并不是~~
  • 像放苹果橘子问题,可以把事件的同步与互斥用箭头表示,每个同步关系用一个针对互斥资源的P(),V()表示;
  • 读者-写者问题,终于用count表示资源读者的数量,为了count错误修改,自然加个mutex的PV锁;
    写者与其他人的互斥用rw锁表示,读者与写者的互斥,读者的同步(on count)非常秀——but only分条件,进行rw的判断,所以应该放开编程,appleorange也可以进行while(apple=0 and orange=0)的判断,不用和书上一致;
  • 吸烟者问题,吸完烟要向供应商发信号,也要用个锁~~

死锁

  • 可剥夺资源:优先级高的可以抢占优先级低的进程的资源;
    OS1_进程与线程的管理_第1张图片
  • 有循环等待未必构成死锁,
  • 若每类资源只有1个资源,资源分配图含圈 ↔ \leftrightarrow 系统出现死锁
    PS:CSDN图片id用的是128位的散列值

死锁处理

OS1_进程与线程的管理_第2张图片


安全状态:按照某种推进顺序,能满足每个进程对资源的最大需求,使每个进程可顺序完成;
死锁避免在分配资源给进程的过程中拒绝进入dangerous state

banker’s alg一般都是DFS+回溯,可以用BFS?


破圈法是为了寻找有环图的最小生成树,

死锁检测定理——待证
1)找出非阻塞(请求的资源数量均不大于系统的空闲资源数量)的非孤立进程Pi,释放Pi所有资源;
2)重复1),若消去所有边,图可完全简化 ↔ \leftrightarrow 不死锁;

预防中的消除循环等待和请求并保持,均不可行,
OS1_进程与线程的管理_第3张图片

你可能感兴趣的:(408,系统架构)