CONCURRENCY THEORY · SYNCHRONIZATION

并发理论与同步机制的可视化实验室

八个交互式模块,将抽象的并发原语——锁、信号量、管程、CAS——转化为可观察、可操控的动态系统。每个模块包含 SVG 可视化、实时控制器与统计指标,帮助你建立对竞争、死锁与无锁编程的直觉。

8 个模块 0 外部依赖 纯 HTML/CSS/JS SVG 矢量可视化
空闲/思考 请求/就绪 等待/阻塞 持有/工作 读取 写入
01 — Mutex & Lock

互斥与锁

多个线程竞争同一把互斥锁进入临界区。同一时刻仅允许一个线程持有锁,其余线程进入等待队列,直至锁被释放后按序唤醒。

VIZ 线程竞争临界区 就绪
模拟速度1.00x
原理说明

互斥锁(Mutex)保证临界区的互斥访问。线程执行 lock() 请求所有权:若锁空闲则获取并进入;若已被占用则阻塞于等待队列。unlock() 释放锁并唤醒一个等待者。

  • 思考(空闲)→ 请求 → 等待/持有
  • 持有者执行临界区后释放,唤醒队首
  • 竞争次数反映锁的争用程度
获取次数
0
等待次数
0
竞争次数
0
释放次数
0
02 — Producer / Consumer

生产者消费者

有界缓冲区上的经典同步问题。生产者在缓冲区满时阻塞,消费者在空时阻塞,通过信号量 empty/full 协调两者速率。

VIZ 有界缓冲区与信号量同步 就绪
生产速率(项/秒)1.0
消费速率(项/秒)1.0
缓冲容量6
原理说明

使用三个信号量:empty(空槽位)、full(已填充)、mutex(缓冲区互斥)。生产者 P(empty)→P(mutex)→放入→V(mutex)→V(full);消费者对称。

  • 满时生产者阻塞于 empty,空时消费者阻塞于 full
  • mutex 保护缓冲区数据一致性
  • 速率失配导致一方持续阻塞
已生产
0
已消费
0
阻塞(满)
0
缓冲填充
0%
03 — Dining Philosophers

哲学家就餐

五位哲学家围坐圆桌,需同时拿起左右两把叉子才能进餐。朴素策略会引发死锁,资源分级与超时回退是两种经典解法。

VIZ 死锁场景与解决方案 就绪
策略
模拟速度1.00x
原理说明

朴素策略:每人先拿左叉再拿右叉,若同时拿左叉则循环等待——死锁。资源分级:始终先取编号较小的叉子,打破循环等待;超时回退:拿不到右叉则释放左叉并重试。

  • 死锁四条件:互斥、持有等待、不剥夺、循环等待
  • 分级破坏循环等待,超时破坏持有等待
用餐次数
0
死锁次数
0
等待中
0
状态
就绪
04 — Reader / Writer

读者写者

共享数据的读写锁:多读者可并发读,写者必须独占。读者优先可能饿死写者,写者优先则抑制新读者。

VIZ 读写锁与优先级策略 就绪
策略
模拟速度1.00x
原理说明

读写锁维护一个读计数与写标志。读者优先:读者无需等待其他读者,仅当有写者时阻塞——可能饿死写者。写者优先:只要有写者在等待,新读者必须阻塞——保证写者最终执行。

  • 读-读兼容,读-写/写-写互斥
  • 优先级策略决定公平性与吞吐权衡
活跃读者
0
活跃写者
0
等待写者
0
完成次数
0
05 — Deadlock Detection

死锁检测

资源分配图中,进程请求资源、资源分配给进程。通过等待图(wait-for graph)检测环——环中的进程即处于死锁状态。

VIZ 资源分配图与环检测 就绪
资源数
原理说明

单实例资源系统中,将"进程 P 请求被进程 Q 占有的资源"化简为等待边 P→Q。若等待图存在环,则环上进程死锁。算法通过 DFS 染色(白/灰/黑)发现回边即定位环。

  • 请求边:进程 → 资源(虚线)
  • 分配边:资源 → 进程(实线)
  • 等待图环 ⟺ 死锁
进程数
4
资源数
4
死锁进程
0
结论
未检测
06 — Semaphore

信号量

计数信号量用整数控制资源许可数:P 操作减一,为零则阻塞;V 操作加一或唤醒一个等待者。二元信号量退化为互斥锁。

VIZ 计数/二元信号量与等待队列 就绪
类型
初始许可数3
模拟速度1.00x
原理说明

信号量 S 是带等待队列的整数。P(S):若 S>0 则 S-- 否则阻塞入队;V(S):若有等待者则唤醒一个,否则 S++。计数信号量可管理多实例资源,二元信号量取值 0/1 等价于互斥锁。

  • P/V 是原子原语(通常由硬件或内核保证)
  • 可用于同步(事件计数)与互斥
当前值
3
等待线程
0
P 次数
0
V 次数
0
07 — Monitor

管程

管程把共享数据与对其的操作封装在一起,内置互斥。条件变量配合 wait/signal 实现同步:满则生产者 wait,空则消费者 wait。

VIZ 条件变量与 wait/signal 就绪
模拟速度1.00x
原理说明

管程内同一时刻仅一个线程活跃。条件变量 cv 提供 wait(cv)(释放锁、阻塞)与 signal(cv)(唤醒一个等待者)。生产者-消费者用 notFull、notEmpty 两个条件变量协调。

  • wait 自动释放管程锁并进入 cv 队列
  • signal 唤醒后唤醒者/被唤醒者之一继续
缓冲填充
0/5
等待生产者
0
等待消费者
0
完成次数
0
08 — CAS & Lock-Free

CAS 与无锁

Compare-And-Swap 是无锁编程的硬件原语:比较内存值与预期,相等则写入新值。CAS 循环实现无锁计数器,但存在 ABA 问题。

VIZ 原子比较交换与 ABA 问题 就绪
场景
模拟速度1.00x
原理说明

CAS(addr, expected, new) 原子地:若 *addr==expected 则 *addr=new 并返回成功,否则返回失败。ABA:值 A→B→A 后,CAS 误以为未变化而成功。引入版本号(tag)使每次写入版本递增即可检测。

  • 无锁计数器:循环重试直至 CAS 成功
  • ABA 危害:栈/链表的悬空指针复用
  • 版本号 / hazard pointer / RCU 解决 ABA
成功
0
失败/重试
0
ABA 事件
0
当前值
0