Golangの反発ロックは君子協定にすぎない

1813 ワード

2018-11-22更新これは私がgoを初めて学んだノートで、これまで関連する開発経験はありませんでした.goの反発ロックがどのように有効になるか知りたかった.この実験により,競合をもたらす可能性のあるコードに対して,通常の流れは -> -> であるべきであることが分かった.ロックが有効になるには、ロックをアクティブに取得する必要があります.一方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 //