二进制信号量来实现计数信号量

一、二进制信号量

struct binary_semaphore {
    enum(zero, one) value;
    queueType queue;
}
void waitB(binary_semaphore s)
{
    if (s.value == 1)
        s.value = 0;
    else//为0阻塞
    {
        place this process in s.queue;
        block this process;
    }
}
void signalB(binary_semaphore s)
{
    if (s.queue.is_empty())
    {//If there are no processes waiting for the semaphore
        s.value = 1;
    }
    else//队列非空,解除一个阻塞
    {
        remove a process P from s.queue;
        place process P on ready list;
    }
}

二、计数信号量

struct semaphore {
    int count;
    queueType queue;//阻塞队列
}
主要是对count的理解,(注意:在++--之前)
count>0时表示还有count个资源可用,
count<0时表示有count个进程正在等待资源
count==0时,wait会阻塞,0个资源可用
count==0时,signal直接通过,0个进程等待
void wait(semaphore s)
{
    s.count--;
    if (s.count < 0)//阻塞
    {
        place this process in s.queue;
        block this process;
    }
}
void signal(semaphore s)
{
    s.count++;
    if (s.count <= 0)//解除一个阻塞
    {
        remove a process P from s.queue;
        place process P on ready list;
    }
}

三、二进制信号量来实现计数信号量

(一)冗长版

struct binary_semaphore {
    enum(zero, one) value;
    queueType queue;
}

//开始时:s1=1,s2=0,整数count的值设置为计数信号量s的初值。
binary_semaphore s1 = 1;
binary_semaphore s2 = 0;
int count =//计数信号量s的初值;

void wait()//看资源,count>=0表示还有count个资源可以分配。
{
    waitB(s1);
    if (count <= 0) {//count==0表示没有资源了,负的也是表示没有资源
        count--;
        signalB(s1);//释放锁,其他可以对count进行操作
        waitB(s2);
        signalB(s1);
    }
    else {//还有资源
        count--;
        signalB(s1);
    }
}
void signal()//看阻塞线程,count<=0表示还有count个进程正在等待。
{
    waitB(s1);
    if (count < 0) {//当count<0时表示有count个进程正在等待资源
        count++;
        signalB(s2);//后面执行wait()中waitB(s2)后的signalB(s1)。写到waitB(s2)后,感觉原子性更强
    }
    else {//count==0表示没有进程等待,正的也是没有进程等待
        count++;
        signalB(s1);
    }
}

(二)精简版

//开始时:s1=1,s2=0,整数count的值设置为计数信号量s的初值。
binary_semaphore s1 = 1;
binary_semaphore s2 = 0;
int count =//计数信号量s的初值;

void wait()//看资源
{
    waitB(s1);
    count--;
    if (count < 0) {
        signalB(s1);//释放锁,其他可以对count进行操作
        waitB(s2);//阻塞
    }
    signalB(s1);
}
void signal()//看阻塞线程
{
    waitB(s1);
    count++;
    if (count <= 0)
    {
        signalB(s2);//后面执行wait()中最后的signalB(s1)
    }
    else
    {
        signalB(s1);
    }
}
posted @ 2022-11-26 12:29  ImreW  阅读(143)  评论(0编辑  收藏  举报