利用记录型信号量机制实现生产者-消费者问题_经典同步互斥问题

一、生产者-消费者问题

又称为有界缓存问题(「bounded buffer」)

「问题描述」:一组生产者进程和消费者进程共享一个初始为空,大小为n的缓冲区。

  • (1)只有当缓冲区没满的时候,生产者才能将消息放进去,否则必须等待。

  • (2)只有当缓冲区不空的时候,消费者才能从中取消息,否则必须等待。

  • (3)由于缓冲区是临界资源,它只允许一个生产者放入消息,也只允许一个消费者拿出消息。

「分析」:首先,生产者之间,消费者之间是互斥的关系,同时生产者消费者之间又是协同的关系,属于进程同步。

信号量实现

  • 计数信号量emptyblock表示buffer中空闲空间的个数(表示同时允许生产者进程的个数)

    • 当buffer满时阻塞生产者进程(用来挂起生产者)
  • 计数信号量fullblock表示buffer中占用空间的个数(表示同时允许消费者进程的个数)

    • 当buffer为空是阻塞消费者进程(用来挂起消费者)
  • 一个二元信号量实现对buffer的互斥访问

「逻辑代码:」

class boundedbuffer{
    
    int buffer_size = N;  //buffer大小
    item_t buffer[buffer_size];
    semaphore mutex(1);
    semaphore emptyblock(buffer_size);
    semaphore fullblock(0);
}
boundedbuffer::productor(){
    emptyblock->sem_wait();  //判断生产者是否要挂起到emptyblock信号量上
    mutex->sem_wait();   // aquire lock
    add item to buffer[];
    mutex->sem_signal();  //unlock
    fullblock->sem_signal();  //buffer占用空间个数加一,判断是否需要唤醒消费者
}
boundedbuffer::consummer(){
    fullblock->sem_wait(); //判断buffer是否为空,消费者是否要挂起到fullblock信号量
    mutex->sem_wait();
    remove a item from buffer[];
    mutex->sem_signal();
    emptyblock->sem_signal();  //buffer空闲空间数量加一,判断是否需要唤醒生产者
}

「分析」:上述逻辑代码中,计数信号量的sem_wait操作和二元信号量的sem_wait操作不能互换(第九、十两行和第十六、十七两行),互换之后会造成死锁,即生产者获得锁之后,此时又正好buffer满,因此被阻塞,而这时锁得不到释放,其他生产者和消费者都得不到执行。

互斥锁+条件变量实现(管程的原理)

  • 一个条件变量notfull来阻塞和唤醒生产者

  • 一个条件变量notempty来阻塞和唤醒消费者

  • 一个互斥量保证互斥

「逻辑代码」

class boundedbuffer{
    
    int size = N;
    item_t buffer[size];
    int count = 0;   //记录buffer状态,初始为空
    mutex_lock mylock;   //互斥锁
    condition notfull, notempty;  //条件变量
}
boundedbuffer::productor(){
    mylock->aquire();  //加锁
    while(count == N) 
        notfull->wait(&mylock);  //阻塞生产者进程到notfull条件变量,会释放锁
    add item to buffer;
    count++;
    notempty->signal();  //若有消费者阻塞,则通过notempty条件变量唤醒消费者
    mylock->realse();  //unlock;
}
boundedbuffer::consumer(){
    mylock->aquire();  //locked
    while(count == 0)  
        notempty->wait(&mylock); //阻塞消费者进程,释放锁
    remove a item from buffer;
    coun
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值