先來看乙個**
package main
import
("fmt"
"runtime"
"sync"
)var
( counter int32
wg sync.waitgroup
)func
main()
func
addcounter
(whoami string
)}
final counter is: 2首先這個程式是起了兩個 goroutine 。每個 goroutine 都對 counter 進行了兩次累加操作,所以理論上 counter 最後應該是 4 而不是 2 。
原因是因為,gerald 協程獲取到 counter 的值後,又讓 seligman 協程去獲取 counter 的值。注意此時 counter 的值還沒改變,所以他們兩個協程都拿到 0 這個值。然後兩個協程又將 value++ 後賦值給 counter,等於說做了兩次 counter = 1 的操作。第二次迴圈也是一樣的原理。所以最後的值是 2 。
這種情況可以用兩中方式避免
for count :=
0; count <
2; count++
這段**其實有點奇怪,為什麼給 counter + 1 要寫得這麼多步。這其實是在模擬 cpu 內部再給你個值+1的時候需要做的操作。首先暫存器會把 counter 的值拿出來儲存在暫存器裡,然後在暫存器裡進行+1操作,最後再把暫存器裡的值放到cpu裡(原理是這樣,若位置錯誤,請及時提醒,見諒)。
而 atomic 就是相當於在 cpu 裡加鎖,讓這三步操作在執行的時候,當前協程不可以被排程切換,等這三步完成之後才可以被排程切換。
package main
import
("fmt"
"runtime"
"sync"
"sync/atomic"
)var
( counter int32
wg sync.waitgroup
)func
main()
func
addcounter
(whoami string
)}
final counter is: 4這次 counter 就變成 4 了,符合預期。
這個應該很熟悉了,互斥鎖,就是在對元素操作之前進行加鎖,操作完了解鎖。就可以保證資料一致了。
package main
import
("fmt"
"sync"
)var
( counter int32
wg sync.waitgroup
mutex sync.mutex
)func
main()
func
addcounter
(whoami string
)}
final counter is: 4叮~?
C 互斥鎖 原子操作的效能測試
atomic原子操作 是在新標準c 11,引入了原子操作的概念,並通過這個新的標頭檔案提供了多種原子運算元據型別,例如,atomic bool,atomic int等等 include include include include include define test data length 1...
golang互斥鎖跟讀寫鎖
golang中sync包實現了兩種鎖mutex 互斥鎖 和rwmutex 讀寫鎖 其中rwmutex是基於mutex實現的,唯讀鎖的實現使用類似引用計數器的功能 1 互斥鎖 其中mutex為互斥鎖,lock 加鎖,unlock 解鎖,使用lock 加鎖後,便不能再次對其進行加鎖,直到利用unlock...
互斥鎖 解決原子性問題
原子性 乙個或多個操作在cpu執行的過程中不被中斷的特性 原子性問題的源頭是執行緒切換,作業系統做執行緒切換依賴於cpu中斷,所以禁止cpu中斷就能禁止執行緒切換。示例 在32位cpu上執行long型別變數的寫操作,long型別變數是64位,所以會被拆分為兩次寫操作 寫高32位和寫低32位 1.單核...