Rumah >pembangunan bahagian belakang >Golang >GO:kekurangan penyegerakan

GO:kekurangan penyegerakan

Linda Hamilton
Linda Hamiltonasal
2024-11-30 01:10:11605semak imbas

GO:lack of synchronization

var a string
var done bool

func setup() {
    a = "hello, world"
    done = true
}

func doprint() {
    if !done {
        once.Do(setup)
    }
    print(a)
}

func twoprint() {
    go doprint()
    go doprint()
}

Analisis Kod

Pembolehubah:

  • a dan b ialah pembolehubah global jenis int, dikongsi oleh semua goroutine.

Fungsi:

  • f():
    • Menulis kepada a dan b secara berurutan (a = 1 dan b = 2).
  • g():
  • Membaca dan mencetak b diikuti dengan a.

Persamaan dalam utama():

  • Fungsi f() dilaksanakan sebagai goroutine berasingan menggunakan go f().
  • Fungsi g() dilaksanakan terus dalam goroutine utama.

Isu Berpotensi:

  • Groutine running f() dan goroutine utama yang melaksanakan g() berjalan serentak.
  • Tulisan kepada a dan b dalam f() mungkin tidak lengkap sebelum g() membaca dan mencetak nilai a dan b.
  • Ini memperkenalkan perlumbaan data, dengan akses serentak (menulis dalam f() dan membaca dalam g()) berlaku pada memori dikongsi (a dan b) tanpa penyegerakan.

Kemungkinan Hasil
Disebabkan kekurangan penyegerakan, output program adalah tidak pasti. Berikut ialah senario yang mungkin:

Kes 1: g() dilaksanakan sebelum f() mengubah suai a dan b:

  • Nilai awal a dan b ialah 0 (lalai untuk int tidak dimulakan dalam Go).
0
0

atau

KES 2: Jika b = 2 selesai sebelum g() tetapi a = 1 tidak, outputnya boleh jadi:

2
0

Pemerhatian Utama
Perlumbaan Data: Akses serentak kepada a dan b tanpa penyegerakan memperkenalkan perlumbaan data. Ini menjadikan tingkah laku program tidak ditentukan dan tidak dapat diramalkan

Membetulkan Kod

  1. Menggunakan penyegerakan.WaitGroup: Pastikan f() selesai sebelum g() dilaksanakan
var a, b int
var wg sync.WaitGroup

func f() {
    a = 1
    b = 2
    wg.Done()
}

func g() {
    print(b)
    print(a)
}

func main() {
    wg.Add(1)
    go f()
    wg.Wait()
    g()
}

  1. Menggunakan Saluran: Isyarat apabila f() selesai:
var a, b int

func f(done chan bool) {
    a = 1
    b = 2
    done <- true
}

func g() {
    print(b)
    print(a)
}

func main() {
    done := make(chan bool)
    go f(done)
    <-done
    g()
}

Di sini, g() menunggu sehingga f() menghantar isyarat ke atas saluran yang telah selesai.

Atas ialah kandungan terperinci GO:kekurangan penyegerakan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn