第六讲 并发控制基础
Peterson算法、模型检验和软件自动化工具
主要内容:
如何阅读理解教科书、互联网上的各种并发程序
如何保证互斥:一个很简单的例子Peterson算法
以及如何画出并发程序状态机的状态
如何保证一个全局变量某一刻只被一个线程写、读?
<=>如何保证一个厕所某一刻只被一个人使用?
Peterson算法
A和B争抢厕所,但是他们都很谦让。
上厕所前,需要事先举旗并贴字。具体来说
- 如果A想要上厕所,会事先举起旗子,旗子上写了A,并且将厕所门口贴上B
- 如果B想要上厕所,会事先举起旗子,旗子上写了B,并且将厕所门口贴上A
准备工作做好以后,下一步将根据旗子和厕所门口的字来决定是否进入厕所。具体来说
- 如果A想要进入厕所,会观察是否有人举起旗子,如果B举了旗子,且门上的贴了B,他将等待,否则A将进入厕所
- 如果B想要进入厕所,会观察是否有人举起旗子,如果A举了旗子,且门上的贴了A,他将等待,否则B将进入厕所
出厕所后,将放下自己的旗子。
这种奇怪的算法将保证A或B进入厕所时,厕所没人。
|
|
我们会不自觉地提出一些问题:
- 如果结束后把门上的字条撕掉,算法还正确吗?
- 在放下旗子之前撕
- 在放下旗子之后撕
- 如果先贴标签再举旗,算法还正确吗?
- 我们有两个 “查看” 的操作
- 看对方的旗有没有举起来
- 看门上的贴纸是不是自己
- 这两个操作的顺序影响算法的正确性吗?
- 是否存在 “两个人谁都无法进入临界区” (liveness)、“对某一方不公平” (fairness) 等行为?
- 都转换成图 (状态空间) 上的遍历问题了!
为了保证peterson的正确性,我们还需要什么?
- 原子指令来保证读/写单个变量是“原子不可分割”的
- 编译器设置屏障
当然这种奇怪算法的正确性需要验证,接下来的所有内容都是围绕验证的。
一种方法是通过人脑来枚举A和B抢着上厕所以及举旗过程的所有状态。模拟多线程执行代码的顺序。
另一种方法是计算机验证,jyy的功底就体现出来了。
使用Python这种动态语言模拟验证状态机正确性。 Model checker
并利用某些库可视化状态机的所有状态。
jyy利用了Generator的一个特性来保存函数运行的上下文。这使得我们能够更方便地模拟状态机的执行过程。
关于Model Checker的Python实现和可视化展示这里就暂且不说了。
所以究竟是怎么做到的,还需要看看2022年的视频
这节课告诉了我们工具的重要性,计算机辅助验证彳亍,人脑模拟计算机不彳亍!