需要解決什麼問題?
讀一個位於 memory 中的變數的值到暫存器中
修改該變數的值(也就是修改暫存器中的值)
將暫存器中的數值寫回memory中的變數值
如果這個操作序列是序列化的操作(在一個thread中序列執行),那麼一切OK,然而,世界總是不能如你所願。
在多CPU體系結構中,執行在兩個CPU上的兩個核心控制路徑同時並行執行上面操作序列,有可能發生下面的場景:
兩個 thread, 一個對 sum 加 1, 一個對 sum 減 1, 兩個都做三次, sum 初始值為 0. 正常來說最後 sum 值應該還是 0.
我們故意在計算完後, 呼叫 schedule() 強迫切換 thread, 可以發現, 這樣執行起來, sum 的值並非預期. 最後變成了 -2, 而非 0
[90334.635512] hello_init: pid=14949
[90334.635699] hello_init: pid=14949, before sum=0
[90334.635714] work_handler1: pid=12886, sum=1
[90334.635717] work_handler1: pid=12886, sum=2
[90334.635719] work_handler2: pid=13336, sum=0
[90334.635722] work_handler1: pid=12886, sum=1
[90334.635724] work_handler2: pid=13336, sum=-1
[90334.635727] work_handler2: pid=13336, sum=-2
[90334.635773] hello_init: pid=14949, after sum=-2
參考:
https://njiot.blogspot.com/2019/12/linux-kernel-spinlock-atomic-ameba.html
https://www.itread01.com/content/1544597825.html
No comments:
Post a Comment