[OS] 进程互斥

1、进程互斥

进程的同步(Synchronization)是解决进程间协作关系( 直接制约关系) 的手段。

进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于另一个协作进程的消息或信号,当一个进程没有得到来自于另一个进程的消息或信号时则需等待,直到消息或信号到达才被唤醒。

进程的互斥(mutual exclusion )是解决进程间竞争关系( 间接制约关系) 的手段。 进程互斥指若干个进程要使用同一共享资源时,任何时刻最多允许一个进程去使用,其他要使用该资源的进程必须等待,直到占有资源的进程释放该资源。

进程互斥关系是一种特殊的进程同步关系,即逐次使用互斥共享资源,也是对进程使用资源次序上的一种协调。

2、进程同步机制遵循的原则

  • 空闲让进:当无进程处于临界区时,临界区处于空闲状态,可以允许一个请求进入临界区的进程进入临界区,有效地使用临界资源。

  • 忙则等待:当有进程进入自己的临界区时,意味着临界资源正在被访问,因而其他的试图进入临界区的进程必须等待,以保证进程互斥地使用临界资源。

  • 有限等待:对要求访问临界资源的进程,必须保证该进程在有效的时间内进入自己的临界区,以免出现死等的情况。

  • 让权等待:当进程不能进入自己的临界区时,应该立即释放处理器,以免陷入“忙等”

3、进程互斥的硬件实现方法

1. 中断屏蔽方法

利用“开 / 关中断指令”实现(与原语的实现思想相同,即在某进程开始访问临界区到结束访问为止都不允许被中断,也就不能发生进程切换,因此也不可能发生两个同时访问临界区的情况)

优点:简单、高效
缺点:不适用于多处理机;只适用于操作系统内核进程,不适用于用户进程(因为开 / 关中断指令 只能运行在内核态,这组指令如果能让用户随意使用会很危险)

2. TestAndSet指令

简称TS 指令,也有地方称为TestAndSetLock 指令,或TSL 指令 . TSL 指令是用硬件实现的,执行的过程不允许被中断,只能一气呵成。以下是用C语言描述的逻辑

/*
* 布尔型共享变量lock 表示当前临界区是否被加锁
* true表示已加锁,false 表示未加锁
*/
bool TestAndTest(bool *lock){
	bool old;
    old = *lock;
    *lock = true;
    return old;
}
/* 以下是使用TSL指令实现互斥的算法逻辑 */
while(TestAndSet(&lock));/*"上锁" 并 "检查" */
//临界区代码...
lock = false;
//剩余区代码...

若刚开始lock 是false,则 TSL 返回的old 值为false,while 循环条件不满足,直接跳过循环,进入临界区。若刚开始lock 是true,则执行 TLS 后old 返回的值为true,while 循环条件满足,会一直循环,直到当前访问临界区的进程在退出区进行“解锁”。

相比软件实现方法,TSL 指令把“上锁”和“检查”操作用硬件的方式变成了一气呵成的原子操作。

优点:实现简单,无需像软件实现方法那样严格检查是否会有逻辑漏洞;适用于多处理机环境
缺点:不满足让权等待原则,暂时无法进入临界区的进程会占用CPU并循环执行TSL指令,从而导致“忙等”。

3. Swap指令

有的地方也叫Exchange 指令,或简称XCHG 指令。
Swap 指令是用硬件实现的,执行的过程不允许被中断,只能一气呵成。以下是用C语言描述的逻辑

/* Swap 指令的作用是交换两个变量的值 */
Swap (bool *a ,bool *b){
	bool temp = *a;
    *a = *b;
    *b = temp;
}

bool old = true;
while( old == true )
    Swap(&lock, &old);
//临界区代码...
lock = false;
//剩余区代码...

逻辑上来看Swap 和TSL 并无太大区别,都是先记录下此时临界区是否已经被上锁(记录在ol量上),再将上锁标记lock 设置为true,最后检查 old,如果 old 为false 则说明之前没有别的进程对临界区上锁,则可跳出循环,进入临界区。

优点:实现简单,无需像软件实现方法那样严格检查是否会有逻辑漏洞;适用于多处理机环境
缺点:不满足“让权等待”原则,暂时无法进入临界区的进程会占用CPU并循环执行TSL指令,从而导致“忙等”。

4、进程互斥的软件实现方法

1. 单标志法。

设置和检查一个标志来标明是否有进程在临界区中

int turn=0

// P0进程
while(turn!=0);
critical section;
turn=1;
remainder section;
// P1进程
while(turn!=1); // 进入区
critical section; // 临界区
turn = 0; // 退出区
remainder section; // 剩余区

两个进程必须交替进入临界区,如果某个进程不再进入临界区,那么另外一个永远也进不去了,违背了“空闲让进”原则。

2. 双标志法先检查。

该算法的基本思想是在每一个进程访问临界区资源之前,先查看一下临界资源是否正被访问,若正被访问,该进程需等待;否则,进程才进入自己的临界区。

flag[i]表示Pi进程是否进入临界区。

// Pi 进程
while(flag[j]); // ①
flag[i]=TRUE; // ③
critical section;
flag[i] = FALSE;
remainder section;
 
// Pj 进程
while(flag[i]); // ② 进入区
flag[j] =TRUE; // ④ 进入区
critical section; // 临界区
flag[j] = FALSE; // 退出区
remainder section; // 剩余区

在并发时Pi和Pj可能同时进入临界区。违背“忙则等待”。

3. 双标志法后检查。

对上个算法进行改版,该算法釆用先设置自己标志为TRUE后,再检测对方状态标志

// Pi进程
flag[i] =TRUE;
while(flag[j]);
critical section;
flag[i] =FLASE;
remainder section;
 
// Pj进程
flag[j] =TRUE; // 进入区
while(flag[i]); // 进入区
critical section; // 临界区
flag [j] =FLASE; // 退出区
remainder section; // 剩余区

当两个进程几乎同时都想进入临界区时,它们分别将自己的标志值flag设置为TRUE,并且同时检测对方的状态(执行while语句),发现对方也要进入临界区,于是双方互相谦让,结果谁也进不了临界区,从而导致“饥饿”现象。

4. Peterson算法。

在上个算法的基础上又设置变量turn,指示优先进入临界区的进程编号。这样可以保证当两个进程同时要求进入临界区,只允许一个进程进入临界区。

// Pi进程
flag[i]=TURE; turn=j;
while(flag[j]&&turn==j);
critical section;
flag[i]=FLASE;
remainder section;
 
// Pj进程
flag[j] =TRUE;turn=i; // 进入区
while(flag[i]&&turn==i); // 进入区
critical section; // 临界区
flag[j]=FLASE; // 退出区
remainder section; // 剩余区

本算法的基本思想是算法一和算法三的结合。利用flag解决临界资源的互斥访问,而利用turn解决“饥饿”现象。

5、信号量

  • P操作:进入区,申请资源;
  • V操作:离开区,释放资源

1. 整型信号量

用一个整数型的变量作为信号量,用来表示系统中某种资源的数量。

int S=1;
void P(int S){//申请资源
	while(S<=0);
	S=S-1;
}

void V(int S){
	S=S+1;
}

存在的问题:不满足“让权等待”原则,会发生忙等

2. 记录型信号量

整型信号量的缺陷是存在“忙等”问题,因此人们又提出了“记录型信号量”,即用记录型数据结构表示的信号量。

class semaphore{
	int value;
	process[] list;
}
void P(semaphore S){//申请资源
	S.value--;
	if(S.value<0){
		block(S.list);
	}
}

void V(semaphoreS){
	S.value++;
	if(S.value<=0){
		wakeup(S.list);
	}
}

当S.value < 0 时表示该类资源已分配完毕,因此进程应调用block 原语进行自我阻塞(当前运行的进程从运行态 ----> 阻塞态),主动放弃处理机,并插入该类资源的等待队列S.list 中。可见,该机制遵循了“让权等待”原则,不会出现“忙等”现象。

若加1后仍是 S.value <= 0,表示依然有进程在等待该类资源,因此应调用wakeup 原语唤醒等待队列中的第一个进程(被唤醒进程从阻塞态 ----> 就绪态)。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值