操作系统导论第31章——信号量

本文探讨了二值信号量如何实现锁,条件变量的使用场景,以及它们在生产者消费者问题、读者写者锁和哲学家就餐问题中的应用。通过实例讲解,深入剖析了信号量在并发控制中的关键作用和可能存在的问题,如公平性和性能优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 定义

一种同步原语,可以用它实现锁和条件变量

 初始化:

#include <semaphore.h>
sem_t s;
sem_init(&s, 0, 1)

第二个参数表示信号量的指针,第二个参数0表示信号量是在同一个进程的多个线程共享的,第三个参数是信号量的初始值

sem_wait

int sem_wait(sem_t* s) {
    1.信号量减1
    2.若信号量为负则等待
}

 sem_post

int sem_post(sem_t* s) {
    1.信号量加1
    2.若有线程等待信号量就唤醒其中一个
}

2. 用二值信号量实现锁

sem_t m;
sem_init(&m, 0, 1)

sem_wait(&m);
//执行业务代码
sem_post(&m)

 

3. 用信号量实现条件变量

4. 信号量解决生产者消费者问题

5. 读者写者锁

含义:一旦一个读者获得了一个锁,其他读者也可以获取这个锁,但是想要获取写锁就必须等到所有读者都结束。

实现关键:第一个读者获取写锁,最后一个读者释放死锁。

分析:可以完成功能,但是有一些缺陷:公平性不好 ,容易饿死写者;用了太多锁,性能不好。

6. 哲学家就餐问题

基本含义:

  • 哲学家围着一个圆桌
  • 哲学家一会思考,不需要餐叉,一会吃饭,需要餐叉
  • 哲学家吃饭要左右手都拿到餐叉

计算机模拟

while(1) {
    think();
    getforks();    
    eat();
    putforks();
}

关键问题:如何实现getforks()和putforks()保证没有死锁,没有哲学家饿死,并且并发度高?

解决办法:

核心:每个餐叉对应一个信号量;修改某个哲学家或者某些哲学家的取餐叉的顺序(先左手还是先右手)

void getforks() {
    if (p == 4) {
        sem_wait(forks[right(p)]);
        sem_wait(forks[left(p)]);
    }
    else {
        sem_wait(forks[left(p)]);    
        sem_wait(forks[right(p)]);
    }
}

 

7. 信号量实现

用到锁和条件变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值