信号量

信号量

2024 南京大学《操作系统:设计与实现》
信号量

用互斥锁实现同步

一个奇妙的想法

  • 创建锁时,立即 “获得” 它 (总是成功)
  • 其他人想要获得时就会等待
    • 此时 release 就实现了同步
  • 一个线程上锁,在另一个线程解锁 😂

让我们来试一试吧 (demo)

  • 先把厕所门都锁上
  • 线程到达以后等待
  • 管理员把所有门都打开
2024 南京大学《操作系统:设计与实现》
信号量

用互斥锁实现计算图

Acquire-Release 实现计算图

  • 为每一条边 e=(u,v)e = (u, v) 分配一个互斥锁 🔒
  • 初始时,全部处于锁定状态
  • 对于一个节点,它需要获得所有入边的锁才能继续
    • 可以直接计算的节点立即开始计算
  • 计算完成后,释放所有出边对应的锁

挺好用 (demo)

  • 甚至比条件变量还好用嘞!
2024 南京大学《操作系统:设计与实现》
信号量

本质:“Release as Synchronization”

Release-Acquire 实现了 happens-before

  • Acquire = 等待 token
  • Release = 发出 token

Token 可以理解为现实生活中的 “资源”

  • 停车场:停车位
  • 游泳馆:获得手环 (token) 的人可以进入更衣室
    • mutex 实现 token 似乎有什么问题?
2024 南京大学《操作系统:设计与实现》
信号量

缺点:token=1\mathrm{token} = 1

2024 南京大学《操作系统:设计与实现》
信号量

于是你发明了信号量!

如果我是游泳馆的老板……

  • 一个能 “计数” 的 mutex: nn 个手环!
    • 手环 = synchronization token
  • mutex 是 n=1n=1 的特殊情况

Acquire

  • 获得手环的同学进入游泳池 (手环不够,等待)

Release

  • 归还一个手环 (一个等待的同学就能得到手环了)
2024 南京大学《操作系统:设计与实现》
信号量

Example: n=2n=2

2024 南京大学《操作系统:设计与实现》
信号量

把 “任何东西” 理解为 Token

停车场有 nn 个车位

  • Acquire: 在有车位时进入停车场
  • Release: 出停车场;车位 + 1

center

2024 南京大学《操作系统:设计与实现》
信号量

把 “任何东西” 理解为 Token (cont'd)

袋子里有 nn 个球

  • Acquire: 从袋子里取一个球
    • 如果没有球,需要等待
  • Release: 向袋子里放一个球
    • 如果有人在等待,直接把球交给他

注意我们可以有多个口袋!

2024 南京大学《操作系统:设计与实现》
信号量

信号量:API

void P(sem_t *sem) {
    // P - prolaag
    //     try + decrease/down/wait/acquire
    atomic {
        wait_until(sem->count > 0) {
            sem->count--;
        }
    }
}

void V(sem_t *sem) {
    // V - verhoog
    //     increase/up/post/signal/release
    atomic {
        sem->count++;
    }
}
2024 南京大学《操作系统:设计与实现》