操作系统(第二章)----3.进程管理

1.基本概念

  • 在多道程序环境下,进程是并发执行的,不同进程之间存在着不同的相互制约关系。为了协调进程之间的相互制约关系,如等待、传递信息等,引入了进程同步的概念。进程同步是为了解决进程的异步问题。
  • 一个简单的例子来理解这个概念。
  • 例如,让系统计算1 + 2x3,假设系统产生两个进程: 一个是加法进程,一个是乘法进程。要让计算结果是正确的,一定要让加法进程发生在乘法进程之后,但实际上操作系统具有异步性,若不加以制约,加法进程发生在乘法进程之前是绝对有可能的,因此要制定一定的机制去约束加法进程,让它在乘法进程完成之后才发生。

(一) 临界资源

  • 系统中的许多资源虽然可以被进程共享使用,但是也存在一些一次只能被一个进程使用的资源,如打印机

将系统中一次只能被一个进程使用的资源称为临界资源

  • 而在程序中对临界资源进行访问的那段代码,成为临界区

(二) 互斥

  • 互斥,亦称间接制约关系进程互斥指当一个进程访问某临界资源时,另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束,释放该资源之后,另一个进程才能去访问临界资源。

(三) 同步机制原则

为了禁止两个进程同时出现在临界区,应满足下列准则:

  • 空闲让进 : 当临界区空闲时,可以让请求的进程直接进入使用
  • 忙则等待 : 当临界区已被占用,则请求的进程必须等待
  • 有限等待 : 对请求访问临界区的进程,应保证在有限时间内进入临界区
  • 让权等待 : 当进程不能进入临界区时,应该让出处理器,防止阻塞发送

2.临界区互斥的软件层面

(一) 单标志法

  • 思想:两个进程在访问完临界区资源后,会把临界区的权限交给另一个进程

在这里插入图片描述

  • 漏洞:若现在turn=0,也即p0可以进入临界区,但是p0因为特殊原因迟迟不进入,导致p1也无法进入,

    这就违背了’空闲让进原则’

(二) 双标志先检查法

  • 设置一个布尔型数组flag[],flag[i]为true就代表进程i想要进入临界区.每个进程在进入临界区之前,先检查有没有别的进程要进入,没有则将flag[i]设置为true:

在这里插入图片描述

  • 漏洞:若p0,p1同时进入,同时将flag设置为true,就违背了’忙则等待的原则’

  • 原因:检测和上锁不是一气呵成的,导致在上锁前,可能有进程切换,导致两个进程一起进入了临界区

(三) 双标志后检查法

  • 设置一个布尔型数组flag[],flag[i]为true就代表进程i想要进入临界区.每个进程在进入临界区之前,先将flag[i]设置为true,再检测有没有别的进程想进入
    在这里插入图片描述

  • 漏洞:显而易见,若同时设为true,就会互相谦让,导致谁也进不了临界区

(四)Peterson算法

  • 该算法可谓对双标志后检查法的改进,思想:若两个进程争夺进入,进程p0发现p1也想进入,就谦让给p1

​ 也即’孔融让梨’的思想

在这里插入图片描述

3.临界区互斥的硬件层面

(一) 中断屏蔽

  • 因为只有在发生中断的时候,cpu才会进行进程切换
  • 因此进程互斥最简单的方法就是屏蔽中断,进而保证互斥的实现

在这里插入图片描述

(二) TestAndSet方法

  • 执行TSL指令时,它的内部运转逻辑:
  • 假设lock现在为false,代表临界资源A空闲,那么我就可以访问这个资源,同时将lock=true,提醒别的进程,这个临界资源A我正在使用,让他们等等
  • 假设lock为true,代表临界资源正在有人使用,所以我必须等待,并且将lock=true,并不影响什么,所以没关系,只是为了让lock为false时可以上锁,将上锁与检查在一个TSL指令完成。
  • 在这里插入图片描述

4.信号量机制

(一) 定义

为什么会出现信号量机制呢?回顾之前的软硬件互斥方法,软件方面上锁和加锁操作无法一气和成,硬件操作不法实现’让全等待’.信号量机制就是为了更高效的实现进程的同步以及互斥

  • 所谓信号量,顾名思义就是用一个变量来代表系统资源的数量,如打印机,则信号量就为1(代表每次只有一个进程能使用打印机).
  • 信号量利用一对原语wait()和singal()实现,通常简称为p,v操作
  • 进程互斥软件层面上锁和加锁操作无法一气和成,而如果能把这些操作都利用原语实现,而原语又是由关中断/开中断实现的,因此,就能实现进程互斥.

(二) 整型信号量

  • 用一个整数型的变量作为信号量,用来表示系统中的某个临界资源
int s=1;

void wait(int s){
    while(s<=0);
    s=s-1;
}
void signal(){
    s++;
}

(三) 记录型信号量

  • 记录型信号量是一个不会出现忙等现象的进程同步机制,除了一个整形外,还要有一个等待队列来保存相关进程
struct{
    int value;
    struct process *L; //等待队列
}

wait(semphare s){
    s.value--;
    if(s.value<0){
        block(s.L) 
        
    }
}

wait函数的意思是: 若资源数小于0,说明以及没有空闲的资源可用了,此时需要利用Block原语将当前进程从运行态转化到阻塞态,让出cpu,并挂到对应资源的阻塞队列中去
这也是为什么记录型信号量可以避免忙等现象的原因

signal(){
    s.value++:
    if(s.value<0){
        wake();
    }
}

signal函数的意思是:释放一个资源后,若value<0,说明队列中还有进程在排队,因此需要利用wakeup原语,唤醒队列中的第一个进程

(四)利用信号量实现同步

设进程P2的语句y需要进程P1的语句X的执行结果作为前驱条件:

int semphare =0
p1{
    ....
    X;
    v(semphare)
}

p2{
    ----
    p(semphare)
    Y
}

(五) 利用信号量实现互斥

设临界资源每次只匀速一个进程访问:

int semphare =1
p1{
    ....
    p(semphare)
    X;
    V(semphare)
}

p2{
    ....
    p(semphare)
    Y;
    V(semphare)
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值