Golang의 데이터 경합: Mutex로 수정

8342 단어 dataracegobahasa
Sebelumnya, kita telah membahas . 데이터는 뮤텍스와 경쟁합니다.

Tapi sebelumnya, kita akan menambahkan sebuah 구조 text serta getter-setter-nya dan mengubah fungsi getText() , 멘자디 세페르티 이니:

package main

import (
    "fmt"
)

func getText() string {
    i := text{txt: "hi"}
    go func() {
        i.Set("hello")
    }()
    return i.Get()
}

type text struct {
    txt string
}

func (t *text) Set(txt string) {
    t.txt = txt
}

func (t *text) Get() string {
    return t.txt
}

func main() {
    fmt.Println(getText())
}



Kalau dilihat secara 시퀀스 다이어그램, ia mirip dengan .
  • 루틴 #1 이동: main()
  • 루틴 #2 이동: fungsi di mana i.Set() 디팡길.



  • Dan jika kita jalankan dengan -race :

    go run -race main.go  
    


    Maka ia juga akan menghasilkan 경고:

    hi
    ==================
    WARNING: DATA RACE
    Write at 0x00c000012230 by goroutine 7:
      main.(*text).Set()
          /Users/pro/Documents/apps/cms/cmd/main.go:20 +0x33
      main.getText.func1()
          /Users/pro/Documents/apps/cms/cmd/main.go:10 +0x2e
    
    Previous read at 0x00c000012230 by main goroutine:
      main.(*text).Get()
          /Users/pro/Documents/apps/cms/cmd/main.go:24 +0xda
      main.getText()
          /Users/pro/Documents/apps/cms/cmd/main.go:12 +0xf1
      main.main()
          /Users/pro/Documents/apps/cms/cmd/main.go:28 +0x24
    
    Goroutine 7 (running) created at:
      main.getText()
          /Users/pro/Documents/apps/cms/cmd/main.go:9 +0xd0
      main.main()
          /Users/pro/Documents/apps/cms/cmd/main.go:28 +0x24
    ==================
    Found 1 data race(s)
    exit status 66
    


    뮤텍스에 대한 솔루션



    Mutex gunanya untuk mencegah agar sebuah variabel tidak diakses secara bersamaan.

    sangat mudah를 구현하십시오. Kita tinggal menempatkan saja 방법 LockUnlock 이 변수는 데이터 경합입니다.

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    func getText() string {
        i := text{txt: "hi"}
        go func() {
            i.Set("hello")
        }()
        return i.Get()
    }
    
    type text struct {
        txt   string
        mutex sync.Mutex
    }
    
    func (t *text) Set(txt string) {
        t.mutex.Lock()
        defer t.mutex.Unlock()
        t.txt = txt
    }
    
    func (t *text) Get() string {
        t.mutex.Lock()
        defer t.mutex.Unlock()
        return t.txt
    }
    
    func main() {
        fmt.Println(getText())
    }
    
    


    Jika kita jalankan dengan -race , 하시냐:

    $ go run -race main.go                                                     main*
    hi
    




    Yang menjadi pertanyaan: mengapa hasilnya tetap hi ?

    Jawabannya adalah: karena go routine #1(main), 셀레사인야 레비 두루 및 랑성 출구.

    Walaupun go routine ke-2 sedang berjalan, karena go routine #1 sudah exit duluan, ya sudah, program selesai.

    좋은 웹페이지 즐겨찾기