并发编程:从入门到放弃
threads.h
但我们还得写并发程序啊!
用状态机理解程序
用状态机模型理解并发程序
还记得第一次学的时候被汉诺塔支配的恐惧?
void hanoi(int n, char from, char to, char via) {
if (n == 1) printf("Move #1 %c -> %c\n", from, to);
else {
hanoi(n - 1, from, via, to);
printf("Move #%d %c -> %c\n", n, from, to);
hanoi(n - 1, via, to, from);
}
}
程序 = 状态机
hanoi(3, 'A', 'C', 'B')
到底是如何运行的? “原始” 的模型 $(M, R)$ 对人类模拟执行太不友好了
hanoi(2, 'A', 'B', 'C')
的 operational semantics希望实现 lock/unlock,保证
void do_sum() {
for (int i = 0; i < n; i++) {
lock(); // 保证顺序、原子性、可见性
// critical section; 临界区
sum++;
unlock();
}
}
假设你和你舍友的行动速度都太快了,必须有一个机制保证你们无法同时进入 WC
int turn, x = 0, y = 0;
void thread1() {
x = 1; turn = T2;
while (y && turn == T2) ;
// critical section
x = 0;
}
void thread2() {
y = 1; turn = T1;
while (x && turn == T1) ;
// critical section
y = 0;
}
Prove by brute force:演示
如何证明 Peterson 算法的正确性?
忘记它的理由
是个不错的练习,但
证明了 Peterson 算法在无编译优化、单处理器上的正确性。 (我们的第一个 non-trivial 并发程序的理解和证明)
在一个简化的程序执行模型上探索了程序的行为
本次课内容与目标
Take-away message