操作系统——同步与互斥

发布于:2025-09-06 ⋅ 阅读:(12) ⋅ 点赞:(0)

目录

1.同步与互斥的概念

1.1临界资源

1.2同步

1.3互斥

2.实现临界区互斥的基本方法

2.1软件实现方法

1)单标志法

2)双标志先检查法

3)双标志后检查法

4)Peterson 算法

2.2硬件实现方法

1)中断屏蔽方法

2)硬件指令方法—TestAndSet指令

3)硬件指令方法—Swap指令

3.互斥锁

1.同步与互斥的概念

虽然多个进程可以共享系统中的各种资源,但其中许多资源一次只能为一个进程所用,一次仅允许一个进程使用的资源称为临界资源,许多物理设备都属于临界资源,如打印机等。此外,还有许多变量、数据等都可以被若干进程共享,也属于临界资源。

1.1临界资源

对临界资源的访问,必须互斥地进行,在每个进程中,访问临界资源的那段代码称临界区,为了保证临界资源的正确使用,可将临界资源的访问过程分成4个部分:

1)进入区。为了进入临界区使用临界资源,在进入区要检查可否进入临界区,若能进入临界区,则应设置正在访问临界区的标志,以阻止其他进程同时进入临界区。                                                2)临界区。进程中访问临界资源的那段代码,又称临界段。
3)退出区。将正在访问临界区的标志清除。
4)剩余区。代码中的其余部分。

1.2同步

同步亦称直接制约关系,是指为完成某种任务而建立的两个或多个进程,这些进程因为需要协调它们的运行次序而等待、传递信息所产生的制约关系。

例如,输入进程A通过单缓冲向进程B提供数据。当该缓冲区空时,进程B不能获得所需数据而阻塞,一旦进程 A 将数据送入缓冲区,进程B就被唤醒。反之,当缓冲区满时,进程 A被阻塞,仅当进程B取走缓冲数据时,才唤醒进程A。

1.3互斥

互斥也称间接制约关系。当一个进程进入临界区使用临界资源时,另一个进程必须等待,当占用临界资源的进程退出临界区后,另一进程才允许去访问此临界资源。

例如,在仅有一台打印机的系统中,有两个进程A和进程B,若当进程A需要打印时,系统已将打印机分配给进程B,则进程A必须阻塞。一旦进程B将打印机释放,系统便将进程A唤醒,并将其由阻塞态变为就绪态。

实现临界区互斥必须遵循的准则

1)空闲让进。临界区空闲时,可以允许一个请求进入临界区的进程立即进入临界区。

2)忙则等待。当已有进程进入临界区时,其他试图进入临界区的进程必须等待。

3)有限等待。对请求访问的进程,应保证能在有限时间内进入临界区,防止进程无限等待。

2.实现临界区互斥的基本方法

2.1软件实现方法

1)单标志法

该算法设置一个公用整型变量turn,指示允许进入临界区的进程编号,当turn=0时,表示允许P0进入临界区;当turn=1时,表示允许P1,进入临界区。即可以使用while关键字实现。

while(turn!=0);

while(turn!=1);

2)双标志先检查法

该算法设置一个布尔型数组 flag[2],用来标记各个进程想进入临界区的意愿,flag[i]=true 表示Pi想要进入临界区(i=0或1)。Pi进入临界区前,先检查对方是否想进入临界区,若想,则等待;否则,将 flag[i]置为true后,再进入临界区;当Pi退出临界区时,将flag[i]置为false。

//进程 P0:

while(flag[1]);//进入区

flag[0]=true;//进入区

critical section;//临界区

flag[0]=false;//退出区

remainder section;//剩余区

//进程 P1:

while(flag[0]);//进入区

flag[1]=true;//进入区

critical section;//临界区

flag[1]=false;//退出区

remainder section;//剩余区

3)双标志后检查法

算法二(双标志先检查法)先检查对方的标志,再设置自己的标志,但这两个操作又无法一气呵成,于是使得两个进程同时进入临界区的问题。因此,想到先设置后检查法,以避免上述问题。算法三先设置自己的标志,再检查对方的标志,若对方的标志为tue,则等待;否则,进入临界区。

//进程 P0:

flag[0]=true;//进入区

while(flag[1]);//进入区

critical section;//临界区

flag[0]=false;//退出区

remainder section;//剩余区

//进程 P1:

flag[1]=true;//进入区

while(flag[0]);//进入区

critical section;//临界区

flag[1]=false;//退出区

remainder section;//剩余区

4)Peterson 算法

Peterson 算法结合了算法一和算法三的思想,利用 flag[]解决互斥访问问题,而利用 turn 解决“饥饿”问题。若双方都争着进入临界区,则可让进程将进入临界区的机会谦让给对方。也就是说,在每个进程进入临界区之前,先设置自己的flag标志,再设置允许进入turn 标志;之后,再同时检测对方的 flag 和 turn 标志,以保证双方同时要求进入临界区时,只允许一个进程进入。

//进程 P0:

flag[0]=true;//进入区

turn=1;//进入区

while(flag[1] && turn==1);//进入区

critical section;//临界区

flag[0]=false;//退出区

remainder section;//剩余区

//进程 P1:

flag[1]=true;//进入区

turn=0;//进入区

while(flag[0] && turn==0);//进入区

critical section;//临界区

flag[1]=false;//退出区

remainder section;//剩余区

2.2硬件实现方法

1)中断屏蔽方法

当一个进程正在执行它的临界区代码时,防止其他进程进入其临界区的最简单方法是关中断。因为CPU只在发生中断时引起进程切换,因此屏蔽中断能够保证当前运行的进程让临界区代码顺利地执行完,进而保证互斥的正确实现,然后执行开中断。

2)硬件指令方法—TestAndSet指令

借助一条硬件指令—TestAndSet 指令(简称 TS 指令)实现互斥,这条指令是原子操作。其功能是读出指定标志后将该标志设置为真。

boolean TestAndSet(boolean *lock){

boolean old;

old=*lock;//old 用来存放 lock 的旧值

*1ock=true;//无论之前是否已加锁,都将lock置为 true

return old;//返回 lock 的旧值

}

3)硬件指令方法—Swap指令

Swap 指令的功能是交换两个字(字节)的内容。

Swap(boolean *a,boolean *b){

boolean temp=*a;

*a=*b;
*b=temp;

}

3.互斥锁

解决临界区最简单的工具就是互斥锁(mutex lock)。一个进程在进入临界区时调用 acquie()函数,以获得锁;在退出临界区时调用release()函数,以释放锁。每个互斥锁有一个布尔变量available,表示锁是否可用。如果锁是可用的,调用 acquire()会成功,且锁不再可用。当一个进程试图获取不可用的锁时,会被阻塞,直到锁被释放。

acquire(){//获得锁的定义
while(!available);
//忙等待
available=false;//获得锁

}
release(){//释放锁的定义

available=true;//释放锁

}
 

acquire()或release()的执行必须是原子操作,因此互斥锁通常采用硬件机制来实现。


网站公告

今日签到

点亮在社区的每一天
去签到