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

GO:kekurangan penyegerakan

Linda Hamilton
Lepaskan: 2024-11-30 01:10:11
asal
496 orang telah melayarinya

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()
}
Salin selepas log masuk

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

Salin selepas log masuk

atau

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

2
0
Salin selepas log masuk

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()
}

Salin selepas log masuk
  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()
}

Salin selepas log masuk

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!

sumber:dev.to
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan