并发控制:同步 (条件变量、信号量、生产者-消费者和哲♂学家吃饭问题)
哲学家吃饭问题 (E. W. Dijkstra, 1960)
哲学家 (线程) 有时思考,有时吃饭
- 吃饭需要同时得到左手和右手的叉子
- 当叉子被其他人占有时,必须等待,如何完成同步?
- 如何用互斥锁/信号量实现?
失败与成功的尝试
失败的尝试
- philosopher.c (如何解决?)
成功的尝试 (万能的方法)
mutex_lock(&mutex);
while (!(avail[lhs] && avail[rhs])) {
wait(&cv, &mutex);
}
avail[lhs] = avail[rhs] = false;
mutex_unlock(&mutex);
mutex_lock(&mutex);
avail[lhs] = avail[rhs] = true;
broadcast(&cv);
mutex_unlock(&mutex);
忘了那些复杂的同步算法吧!
你可能会觉得,管叉子的人是性能瓶颈
- 一大桌人吃饭,每个人都叫服务员的感觉
- Premature optimization is the root of all evil (D. E. Knuth)
抛开 workload 谈优化就是耍流氓
- 吃饭的时间通常远远大于请求服务员的时间
- 如果一个 manager 搞不定,可以分多个 (fast/slow path)
- 把系统设计好,使集中管理不成为瓶颈
- Millions of tiny databases (NSDI'20)
- 把系统设计好,使集中管理不成为瓶颈
Conditional Variables (条件变量, CV)
把 pc.c 中的自旋变成睡眠
- 在完成操作时唤醒
条件变量 API
- wait(cv, mutex) 💤
- 调用时必须保证已经获得 mutex
- 释放 mutex、进入睡眠状态
- signal/notify(cv) 💬 私信:走起
- 如果有线程正在等待 cv,则唤醒其中一个线程
- broadcast/notifyAll(cv) 📣 所有人:走起
- 唤醒全部正在等待 cv 的线程
条件变量:实现生产者-消费者
void Tproduce() {
mutex_lock(&lk);
if (count == n) cond_wait(&cv, &lk);
printf("("); count++; cond_signal(&cv);
mutex_unlock(&lk);
}
void Tconsume() {
mutex_lock(&lk);
if (count == 0) cond_wait(&cv, &lk);
printf(")"); count--; cond_signal(&cv);
mutex_unlock(&lk);
}
- (Small scope hypothesis)
条件变量:实现并行计算
struct job {
void (*run)(void *arg);
void *arg;
}
while (1) {
struct job *job;
mutex_lock(&mutex);
while (! (job = get_job()) ) {
wait(&cv, &mutex);
}
mutex_unlock(&mutex);
job->run(job->arg); // 不需要持有锁
// 可以生成新的 job
// 注意回收分配的资源
}
99% 的实际并发问题都可以用生产者-消费者解决。
void Tproduce() { while (1) printf("("); }
void Tconsume() { while (1) printf(")"); }
在 printf
前后增加代码,使得打印的括号序列满足
- 一定是某个合法括号序列的前缀
- 括号嵌套的深度不超过 n
- n=3,
((())())(((
合法 - n=3,
(((())))
,(()))
不合法
- n=3,
- 同步
- 等到有空位再打印左括号
- 等到能配对时再打印右括号
https://jyywiki.cn/OS/2022/slides/6.slides#/1/3
【并发控制:同步 (条件变量、信号量、生产者-消费者和哲♂学家吃饭问题) [南京大学2022操作系统-P6]】https://www.bilibili.com/video/BV17T4y1S7RS
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2020-09-21 低代码 Low-Code
2020-09-21 json vs pickle
2019-09-21 agentzh 的 Nginx 教程(版本 2019.07.31)
2019-09-21 URL 重定向机制
2018-09-21 批量索引以提高索引速度 -d --data-binary
2018-09-21 相似度模型 similarity model
2018-09-21 开箱即用 || 自定义 分析器