复习
本次课回答的问题
本次课主要内容
互斥:保证两个线程不能同时执行一段代码。
插入 “神秘代码”,使得 sum.c (或者任意其他代码) 能够正常工作
void Tsum() {
// 神秘代码
sum++;
// 神秘代码
}
__sync_synchronize();
x = 1; // 或 int t = x;
__sync_synchronize();
int locked = UNLOCK;
void critical_section() {
retry:
if (locked != UNLOCK) {
goto retry;
}
locked = LOCK;
// critical section
locked = UNLOCK;
}
和山寨 alipay.c 完全一样的错误
A 和 B 争用厕所的包厢
进入临界区的情况
一些具体的细节情况
枚举状态机的全部状态 (假设没有乱序、每步执行一行)
int x = 0, y = 0, turn = A;
void TA() {
while (1) {
/* PC=1 */ x = 1;
/* PC=2 */ turn = B;
/* PC=3 */ while (y && turn == B) ;
critical_section();
/* PC=4 */ x = 0; } }
void TB() {
while (1) {
/* PC=1 */ y = 1;
/* PC=2 */ turn = A;
/* PC=3 */ while (x && turn == A) ;
critical_section();
/* PC=4 */ y = 0; } }
我们 (在完全不理解算法的前提下) 证明了 Sequential 内存模型下 Peterson's Protocol 的 Safety。它能够实现互斥。
并发编程比大家想象得困难
和一些现状
并发算法的设计困境
解决困境 💡
选择正确的语言
选正确的语言机制
死循环也能返回?
def numbers(init=0, step=1):
n = init
while True:
n += step
yield n
>>> g = numbers()
>>> g
<generator object numbers at 0x107f873c0>
>>> g.__next__()
1
>>> g.__next__()
2
g = numbers()
是一个状态机 (类似是线程,但不并发执行)
g.__next__()
会切换到状态机执行,直到 yield
StopIteration
异常在 C 语言里同样可以实现 (MiniLab 2)
yield()
切换到另外的状态机/线程执行class Mutex:
locked = ''
def T1(self):
yield checkpoint()
while True:
yield checkpoint()
while self.locked == '🔒':
yield checkpoint()
pass
yield checkpoint()
self.locked = '🔒'
...
thread_state = mutex_obj().T1()
thread_state.__next__() # 单步执行一行; see: execute()
什么是状态空间?
[0] T1
[1] T2
[0,0] T1 -> T1
[0,1] T1 -> T2
[0,0,0] T1 -> T1 -> T1
[0,0,1] T1 -> T1 -> T2
[0,1,0] T1 -> T2 -> T1
... ...
Model checking is a method for formally verifying finite-state systems——只要能为系统建立模型,就能用 prove by brute-force 证明正确/找到错误。
Model checker 的一切就是状态机!
真实程序的状态空间太大?
不满足于简单的内存模型?
没有人能阻止程序员写 bug,但
工具 可以。
至今为止我们用过的自动化工具 (他们拯救了你无数次)
-Wall -Werror
这门课的另一个 take-away
本次课回答的问题
Take-away message