记录型信号量

 在整型信号量中,如果某个进程一直等待,不妨把这个进程放入阻塞队列,为CPU腾出空间,当该进程条件满足再将其从阻塞队列中拿出。因此记录资源的类型发生了变化:

typedef struct{
    int value;
    struct process_control_block * list;
} semaphore;

value表示资源数量,list表示该类资源的阻塞队列。wait和signal也发生了变化:

wait(semaphore *S)
{
    S->value--;
    if (S->value<0) 
        block(S->list);
}

signal(semaphore *S)
{
    S->value++;
    if (S->value<=0) 
        wakeup(S->list);
}

整体的互斥模式结构不变:

semaphore  mutex = 1;
        begin
        parbegin
            process 1: begin
                           repeat
                               wait(mutex);
                               critical section
                               signal(mutex);
                               remainder section
                           until false;
                       end
            process 2: begin
                           repeat
                               wait(mutex);
                               critical section
                               signal(mutex);
                               remainder section
                            until false; 
                       end
        parend  
        end     

改变后的代码需要重新梳理逻辑,假设现在mutex=1,P1执行wait操作,value--表示资源使用,当前资源mutex=0,那么接下来的判断value<0不成立,不需要将进程放入阻塞队列。与此同时P2也执行了wait操作,value--,那么mutex=-1表示资源不足,if判断通过,P2被放入阻塞队列。

P1执行完临界区代码执行signal操作,value++表示资源回收,当前mutex=0,满足if条件,从阻塞队列中拿出进程P2。接下来P2进程由于已经执行了wait操作开始继续执行临界区代码,然后signal操作回收资源,最后mutex=1。

细心观察可以发现一个规律:信号量value>0,value表示可用资源的数量;value<0,value表示因该类资源阻塞的进程数量。

这里两个if判断容易混淆,记不清哪个有等于号,其实这只是一个逻辑,wait和signal操作还可以这样写:

wait(semaphore *S)
{    
    if (S->value<=0) 
        block(S->list);
    S->value--;
}

signal(semaphore *S)
{    
    if (S->value<0) 
        wakeup(S->list);
    S->value++;
}

先判断,那么等于号就在wait这里;后判断,等于号就在signal那里。

 

记录型信号量也是有缺点的,比如现在的情景是两个进程A和B,共享数据D和E,为其分别设置互斥信号量Dmutex和Emutex,初值均为1。使用记录型信号量要保证wait和signal成对出现使用,于是代码如下:

Process  A:
    wait(Dmutex);
    wait(Emutex);
        // 使用D、E
    Signal(Dmutex)
    Signal(Emutex)

Process  B:
    wait(Emutex);
    wait(Dmutex);
       // 使用D、E
    Signal(Dmutex)
    Signal(Emutex)

假如进程A执行wait(Dmutex)操作,Dmutex--;同时进程B执行wait(Emutex)操作,Emutex--;那么A进程再执行wait(Emutex)操作时就会使进程A进入阻塞状态;同样的,B进程接下来执行wait(Dmutex)操作也会让进程B进入阻塞队列。两个进程都进入阻塞队列,就成了死锁现象。所以共享的资源越多,死锁的可能性越大。

为了解决记录型信号量中的死锁问题,出现了AND型信号量。

传送门:AND型信号量

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值