第28章 锁

This program, x86.py, allows you to see how different thread interleavings either cause or avoid race conditions. See the README for details on how the program works and answer the questions below

flag.s是对图28.1程序的汇编实现

python3 x86.py -p flag.s -c

count最终为2,程序按预期工作

python3 x86.py -p flag.s -M flag,count -R ax,bx -c

count最终为4,代码先执行Thread0,待Thread0结束后,执行Thread1

python3 x86.py -p flag.s -a bx=2,bx=2 -M flag,count -R ax,bx -c

只有当中断频率为11的倍数时,程序才能按预期工作,因为有11条指令循环(1000-1010)

第12条结束指令(1011 halt)只执行一次,因此不考虑在内

当中断频率不是11的倍数时,都有可能发生图28.2的问题,即中断发生在指令1001和指令1003之间,导致锁的失效

python3 x86.py -p flag.s -a bx=50,bx=50 -i 11 -M flag,count -R ax,bx -c

获取锁:

mov  $1, %ax
xchg %ax, mutex     # atomic swap of 1 and mutex
test $0, %ax        # if we get 0 back: lock is free!

jne  .acquire       # if not, try again

释放锁:

mov  $0, mutex

程序会按预期执行,但是会导致CPU使用率不高,因为会有自旋发生

可以用自旋指令数/总指令数来衡量

令bx=5

当i=11,自旋指令数/总指令数=0,说明没有自旋发生

当i=4,自旋指令数/总指令数=44/156=28.2%,说明有28.2%的指令是在自旋,浪费CPU资源

python3 x86.py -p test-and-set.s -a bx=5,bx=5 -i 4 -M mutex,count -R ax,bx -c

程序可以保证正确执行

python3 x86.py -p test-and-set.s -a bx=5,bx=5 -i 4 -M mutex,count -R ax,bx -P 000111 -c

Peterson’s algorithm的汇编实现

这3条指令可以防止出现图28.2的情况

mov turn, %ax
test %cx, %ax           # compare 'turn' and '1 - self'
je .spin1               # if turn==1-self, go back and start spin again

python3 x86.py -p peterson.s -a bx=0,bx=1 -i 50 -M flag,turn,count -R ax,bx,cx -c

python3 x86.py -p peterson.s -a bx=0,bx=1 -M flag,turn,count -R ax,bx,cx -P 000000111111

是图28.7的汇编实现

python3 x86.py -p ticket.s -a bx=1000,bx=1000 -i 50 -M ticket,turn,count -R ax,bx,cx -c

Fetch-And-Add在Test-And-Set的基础上,保证了公平性,可以让每一个线程都有相等的机会运行,不会饿死

但仍然会有自旋等待发生

在test-and-set.s的基础上改变跳转条件并增加了3条指令

mov  $1, %ax
xchg %ax, mutex     # atomic swap of 1 and mutex
test $0, %ax        # if we get 0 back: lock is free!

je .acquire_done
yield               # if not, yield and try again
j .acquire
.acquire_done

python3 x86.py -p yield.s -i 5 -a bx=5,bx=5 -M mutex,count -R ax,bx -c

相比test-and-set.s多出来了这2条指令

mov  mutex, %ax
test $0, %ax
jne .acquire

而这3条指令正是flag.s中用于判断是否有锁的指令

Original: https://blog.csdn.net/suitaox26456/article/details/127817531
Author: 碰碰狗
Title: 第28章 锁

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/657531/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球