进程的同步

进程的同步:

我们知道在现代计算机的条件下,很多计算机都是多到程序处理的,既程序之间的并发,这里我们就来具体了解一下进程的同步。

我们一般把异步环境下,一组并发进程因直接制约而互相发送消息,互相合作,互相等待,使得各自按照一定的速度执行的过程,叫做进程同步。进程同步难免就会涉及到资源共享的问题了,而且进程之间的制约关系主要分为以下两种:

直接关系:

又称为同步关系,既有些程序在完成某一功能时,会创建多个进程,这些进程也会相会配合完成这一功能。对于共享资源的访问,进程之间则是按照一定的先后顺序去访问这一资源。直接关系主要强调进程对共享资源访问的先后顺序。

举个栗子:

有输入进程A和输出进程B相互配合,共享一段缓冲区,首先由A输入数据到缓冲区,然后由B从缓冲区中读取数据并输出,如果是先是B执行的话,则缓冲区中没有数据,导致进程B被堵塞。当A执行完后,B再被唤醒。

互斥关系:

是直接关系的一个特例,既多个程序在并发执行时,由于会涉及到资源的共享,如打印机,I/O设备等,这些资源在被使用的时候,同一时刻,只能被一个程序所使用,从而在进程之间形成了互斥的制约关系。这些资源也称为边界资源。互斥关系主要强调进程之间对共享资源的互斥访问。

举个栗子:

如我们熟悉的抢椅子游戏,有A,B ,2个人,但是只有1个椅子,随着音乐的停止,这两个人就会争着抢夺那一个椅子所以无外乎会有以下几种情况:1.A坐在了椅子上 2.B坐在了椅子 3.AB都坐在了椅子上(这种情况很少见,但是也不是没有,所以进程在竞争资源时,也会出现这种与时间有关的错误。)

临界区问题:

临界区就是指进程中访问临界资源(就是互斥关系里的共享资源)的那段代码,显然,如果要实现进程之间互斥的访问边界资源,就需要进程互斥的执行各自的临界区代码。解决临界区问题的方法有多种,但是都要遵循以下四条准则:

1.空闲让进:

既边界资源处于空闲状态时,则可以允许一个进程来访问这个边界资源。

2.忙则等待:

既边界资源在被使用的时候,如果还有进程需要访问这段资源,则该进程需要等待。

3.有限等待:

既等待使用边界资源的进程,要在有限的时间里进入自己的边界区,不要出现“死等”的现象。

4.让权等待:

当进程不能进入自己的边界区时,既进程处于等待状态时,应释放对cpu的使用权,以免陷入“忙等”状态。该原则,尽量遵循,但是也可以不遵循。

解决边界区问题主要有软件同步机制,硬件同步机制,信号量机制,因为信号量机制是目前最为广泛运用的机制,所以主要了解一下信号量机制。

信号量机制:

总所周知信号灯在交通中的运用,人们在过马路时,根据信号灯的颜色来执行相应的动作,这里的信号量机制就和这个很类似。

信号量机制由迪杰斯特拉提出,没错就是那个求最短路径算法的男人,这种机制应用广泛,无论是单处理机还是多处理机都有运用,可以说是“老少通吃”了,哎,没办法,谁让“人家”那么优秀呢。

信号量机制主要分为以下几种:

整型信号量:

迪杰斯特拉将整形信号量定义为 一个整型变量S(这里S是变量名),S的初始值为边界资源的个数,它的特别之处在于,仅能通过两个标准的原子操作(系统态下具有某一特定功能的不可分割不可中断的程序段)来对它进行修改,既wait(P)操作,signal(V)操作。

P操作:

主要是判断变量S是否小于等于0,如果小于0则啥也不干,如果大于0则让S自减。既使用边界资源时执行。伪代码如下:

wait(S){

while(S<=0) ;

s--;

}

V操作:

主要是让S自增,既返还边界资源时,执行。伪代码如下:

signal(S)

{

s++;

}

整型信号量只是符合了边界区问题的前三项原则,没有执行让权等待原则,这样会使进程处于“忙等”状态。

记录型信号量:

记录型信号量,在整型信号量的基础上,通过增加一个链表,用来记录处于等待状态的进程,以及堵塞原语和唤醒原语,实现了“让权等待”原则,解决了进程的“死等”问题。主要过程如下:

首先定义一个结构体,将用于记录资源数目的变量value和及记录等待进程的链表list整合在一起。伪代码如下:

typedef struct

{

int value;

struct process_control_block * list;

} semaphore;

P操作:

因为采取了进程释放cpu资源可以等待的方法,所以会导致等待进程有多个进程的情况,所以用list来记录这些等待进程,之后就是每有一个资源要被使用时,value值就会自减,同时会执行block原语(堵塞原语)让该进程处于堵塞状态并记录在list中。伪代码如下:

wait(semaphore * s)

{

s->value--;

if(s->value<0)

block(s->list);

}

V操作:

当有一个资源被使用完后,就会执行V操作,返还资源,使value自增,同时判断list的值如果是小于等于0的话,就说明还有等待的进程需要使用wakeup原语唤醒,可以执行了,以及从list中清除该进程的记录。伪代码如下:

signal(semaphore *s)

{

s->value--;

wakeup(list);

}

这里的解决方法与整型信号量一样都是针对的多个并发进程共享一个资源的问题。对此也有多个进程访问多个共享资源的问题,咋采用以下方法:

AND信号量:

死锁:

当有进程A 和进程B需要访问共享资源D和F时,为资源D分配信号量Dmutex=1,为资源F分配信号量Fmutex=1,假设用以下的次序来执行P操作的话:

A: wait(Dmutext) Dmutext=0;

B: wait(Fmutext) Fmutext=0;

A: wait(Fmutext) Fmutext=-1;

B: wait(Dmutext) Dmutext=-1;

当我们按照这样的次序执行下去时,既进程A和B都会释放掉spu的使用权而处于堵塞状态了,A想唤醒的话,就需要B先把资源F释放了,但是B想把资源F释放掉就需要A先把资源D释放掉。彼此互相制约,就出现了“死锁”现象了。当进程之间对共享资源的要求越多,死锁的可能性就越大了。

接下来就来介绍AND信号量时如何解决这一问题的。

基本思想:

将进程在整个执行过程中所需要的所有资源,全部一次性的分配给它,等它使用完后,在一次性全部释放,只要有一个资源分配不到,就啥也不给它。

P操作:

通过判断该进程所需的所有资源是否全部可以分配给该进程,如果可以,则分配,反之,则将该进程进行堵塞,加入到等待队列中。伪代码如下:

Swait(S1,S2...Sn)
{
    while(true)
    {
        if(S1>=1&& S2>=1...&&Sn>=1)
            for(i=1;i<=n;i++) Si--;
        else
            将该进程进行堵塞,加入到等待队列中;
    }
}
V操作:

将该进程所用到的资源全部释放。伪代码如下:

Ssignal(S1,S2...Sn)
{
    while(true)
    {
        for(i=1;i<=n;i++)
        Si++;
    }
}

信号量集:

前面介绍的信号量机制都是只能对信号量实现自增或自减,既只能对临界资源进行一个单位的释放或申请。当我们需要一次申请N个单位时,一次一次的来过于缓慢,甚至会增加死锁的概率,此外在有些情况下,有些资源的分配会设置下限值,当资源的数目低于这一下限值时,就会受到管制,不再分配此资源。

所以信号量集是在AND信号量的基础上,加以扩充,既在进程所需的各种资源和数目都足够的情况下才会为该进程分配资源,释放也是一次性释放掉该进程所占用的全部的资源。

P操作:

既通过进程所需的所有资源的数目如果都大于等于下限值,也就是S(i)>=S(min),否则,不予分配,撤销cpu使用权,进入等待队列。伪代码如下:

Swait(S1,t1,d1 ; S2,t2,d2 ... ; Si,ti,di)//这里S表示信号量,t表示下限值,d表示需要申请的资源单位
{
    while(true)
    {
        if(S1>=t1&& S2>=t2...&&Sn>=ti)
            for(i=1;i<=n;i++) Si-=di;
        else
            将该进程进行堵塞,加入到等待队列中;
    }
}
V操作:

既一次性释放掉占用的所有资源。伪代码如下:

Ssignal(S1,d1 ; S2,d2 ; ... ;Sn,dn)
{
    while(true)
    {
        for(i=1;i<=n;i++)
        Si+=di;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码商道

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值