9 信号量和管程
信号量
-
锁的不足
- 多线程同时执行访问临界区
- 互斥和条件同步
-
含义
- 包含一个信号量sem(semaphore,有符号整数) 和两个原子操作:P操作和V操作
- sem变量受保护。初始化后,改变信号量的唯一方法是P()和V()。两个操作必须是原子的
- P()能够阻塞,V()不会阻塞
- 假定信号量是公平的:实践中,通常使用FIFO,利用队列决定唤醒哪个进程 ⇒ 上一章的Spinlock是FIFO类型吗?
- 包含一个信号量sem(semaphore,有符号整数) 和两个原子操作:P操作和V操作
-
用途
- 互斥
- 条件同步(调度约束 —— 一个进程等待另一个进程的事件发生)
-
两种类型信号量
-
二进制信号量:0或1 ⇒ 模拟lock操作
-
模拟lock操作
mutex = new Semaphore(1); //sem初值置1 ... mutex->P(); ... Critical Section; ... mutex->V();
-
实现简单的调度/同步约束(线程A的P()后面的代码需等待线程B执行到V()后才继续执行)
-
-
一般/计数信号量:可取任何非负值
-
解决复杂的调度/同步问题
-
-
-
-
-
-
信号量的实现
class Semaphore{ int sem; waitQueue q; } Semaphore::P(){ //该原子操作的语义 sem--; if(sem < 0){ Add this thread t to q; block(t); } } Semaphore::V(){ //该原子操作的语义 sem++; if(sem <= 0){ Remove a thread t from q; wakeup(t); } }
-
不足
- 读/开发代码比较困难
- 程序员必须非常精通信号量
- 容易出错
- 使用的信号量被另一个线程占用
- 忘记释放信号量
- 不能解决死锁问题
- 读/开发代码比较困难
管程
- 抽象程度比信号量更高。处于语言层面
- 目的:分离互斥和条件同步的关注
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义