理解并发程序执行 (Peterson算法、模型检验与软件自动化工具

 

本次课回答的问题

  • Q: 如何理解各种并发程序?

Take-away message

  • 并发程序 = 状态机
    • 线程共享内存
    • 每一步非确定选择线程执行
  • 画状态机就对了
    • 当然,用工具帮你画 (model checker)

 

画状态机

初始状态

pc1 pc2 x y  turn

(1  1 0 0 A)

T1执行

 

 

 

 

 

 会abort

#include "thread.h"

#define A 1
#define B 2

atomic_int nested;
atomic_long count;

void critical_section()
{
    long cnt = atomic_fetch_add(&count, 1);
    assert(atomic_fetch_add(&nested, 1) == 0);
    atomic_fetch_add(&nested, -1);
}

int volatile 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;
    }
}

int main()
{
    create(TA);
    create(TB);
}

  

 

习题:证明 Peterson 算法正确,或给出反例
进入临界区的情况

如果只有一个人举旗,他就可以直接进入
如果两个人同时举旗,由厕所门上的标签决定谁进
手快有(被另一个人的标签覆盖)、手慢无
一些具体的细节情况

A 看到 B 没有举旗
B 一定不在临界区
或者 B 想进但还没来得及把 “A 正在使用” 贴在门上
memory ordering
A 看到 B 举旗子
A 一定已经把旗子举起来了
 

https://jyywiki.cn/OS/2022/slides/4.slides#/1/3

Peterson 算法

正确性不明的奇怪尝试 (Peterson 算法)

A 和 B 争用厕所的包厢

  • 想进入包厢之前,A/B 都要先举起自己的旗子
    • A 确认旗子举好以后,往厕所门上贴上 “B 正在使用” 的标签
    • B 确认旗子举好以后,往厕所门上贴上 “A 正在使用” 的标签
  • 然后,如果对方的旗子举起来,且门上的名字不是自己,等待
    • 否则可以进入包厢
  • 出包厢后,放下自己的旗子

 

 

  • 处理器默认不保证 load + store 的原子性

失败的尝试

int locked = UNLOCK;

void critical_section() {
retry:
  if (locked != UNLOCK) {
    goto retry;
  }
  locked = LOCK;

  // critical section

  locked = UNLOCK;
}

和山寨 alipay.c 完全一样的错误

 

【理解并发程序执行 (Peterson算法、模型检验与软件自动化工具) [南京大学2022操作系统-P4]】https://www.bilibili.com/video/BV15T4y1Q76V

 

posted @ 2022-09-14 19:22  papering  阅读(184)  评论(0编辑  收藏  举报