Golangの反発ロックは君子協定にすぎない
1813 ワード
2018-11-22更新これは私がgoを初めて学んだノートで、これまで関連する開発経験はありませんでした.goの反発ロックがどのように有効になるか知りたかった.この実験により,競合をもたらす可能性のあるコードに対して,通常の流れは
このノートで表現したいのは、ロックの正しい使い方は
コメントエリアの斧正さん、ありがとうございました.修正後の本文は以下の通りです.
golangの反発ロックでは、メモリまたはコードまたは変数をロックすることはできません.
次のコードは、goroutineを起動して変数をロックし、main関数で直接操作します.
結果
結果はmodifyで変数が確かに変更されたことを示しますが、modifyがロックされている間もmain関数は変数の変更に成功しました.つまり、
goのmutexは君子協定にすぎない:race conditionをもたらす可能性がある場所で、ロック
したがって、race conditionをもたらす可能性のあるすべてのコードに
mian関数の正しい使い方は
出力結果
その結果、mainはロックを取得する際にブロックされ、modifyが実行されるとロックが取得され、変数が変更されることになります.
延長
-> ->
であるべきであることが分かった.ロックが有効になるには、ロックをアクティブに取得する必要があります.一方mysqlでは、あるレコードがロックされている場合(select for updateなど)、他の書き込み操作はアクティブにロックを取得する必要がなく、自動的にブロックされて実行できません.mysqlでupdateでロックを取得する操作は自動的で、ユーザーに透明です.だから私はずっと
と勘違いしていたので、このノートを持っていました.このノートで表現したいのは、ロックの正しい使い方は
-> ->
で、開発はこの約束を守らなければならない.そうしないと、ロックは発効しない.それだけです.コメントエリアの斧正さん、ありがとうございました.修正後の本文は以下の通りです.
golangの反発ロックでは、メモリまたはコードまたは変数をロックすることはできません.
次のコードは、goroutineを起動して変数をロックし、main関数で直接操作します.
var wg sync.WaitGroup
var name = "hello world"
var mu sync.Mutex
func main() {
wg.Add(1)
go modify()
結果
in modify modify
in main dddddd
in modify dddddd
結果はmodifyで変数が確かに変更されたことを示しますが、modifyがロックされている間もmain関数は変数の変更に成功しました.つまり、
Lock
はメモリや変数を保護することができず、ロックされたコードを気にせずに勝手に操作できることを意味します.goのmutexは君子協定にすぎない:race conditionをもたらす可能性がある場所で、ロック
mu.Lock()
を取得しようとすることによって操作できるかどうかを決定する.強制的な保護ではありません.したがって、race conditionをもたらす可能性のあるすべてのコードに
Lock()
を追加する必要があります.そうしないと、このコードはロックの存在を無視し、自由に操作できます.mian関数の正しい使い方は
です.func main() {
wg.Add(1)
go modify()
出力結果
in modify modify
in modify modify
in main dddddd
その結果、mainはロックを取得する際にブロックされ、modifyが実行されるとロックが取得され、変数が変更されることになります.
延長
mutex
変数は、異なる操作オブジェクトを保護するためのコードセグメントを複数定義することができる.ただし、同じオブジェクトを保護する必要があるコードは、同じmutex
を使用して有効にする必要があります.必要に応じて定義したほうがいいです.type data struct{
muIn sync.Mutex // data
v int
}
var muOut sync.Mutex //