Rumah > pembangunan bahagian belakang > Golang > Mengapa Goroutine Saya Menambah Pembolehubah Menghasilkan Keputusan Yang Tidak Dijangka?

Mengapa Goroutine Saya Menambah Pembolehubah Menghasilkan Keputusan Yang Tidak Dijangka?

Mary-Kate Olsen
Lepaskan: 2024-10-29 20:38:29
asal
779 orang telah melayarinya

Why Does My Goroutine Incrementing a Variable Produce Unexpected Results?

Adakah Ini Hasil Pengoptimuman Pengkompil?

Dalam coretan kod ini, goroutine dilancarkan dan berulang kali menambah pembolehubah i:

<code class="go">package main

import "time"

func main() {
    i := 1
    go func() {
        for {
            i++
        }
    }()
    <-time.After(1 * time.Second)
    println(i)
}</code>
Salin selepas log masuk

Walau bagaimanapun, output sentiasa 1. Tingkah laku ini boleh dikaitkan dengan model memori Go dan pelaksanaan khusus kod ini.

Model Memori Go

Model memori Go mentakrifkan syarat di mana bacaan pembolehubah dalam satu goroutine boleh dijamin untuk memerhatikan nilai yang dihasilkan dengan menulis kepada pembolehubah yang sama dalam goroutine yang berbeza. Ia menekankan kepentingan penyegerakan untuk akses serentak kepada data yang dikongsi.

Mengabaikan Penyegerakan

Dalam kod yang diberikan:

  • Penugasan kepada i (iaitu, i ) tidak diikuti oleh sebarang peristiwa penyegerakan, menunjukkan bahawa perubahan mungkin tidak dapat dilihat dengan serta-merta kepada gorouti lain.
  • Pengkompil boleh mengoptimumkan pengoptimuman gelung ini dengan memudahkannya kepada no-op.

Pengoptimuman oleh Pengkompil

Pengkompil yang agresif mungkin memadamkan pernyataan i, dengan berkesan mengurangkan goroutine kepada:

<code class="go">for {}</code>
Salin selepas log masuk

Contoh dengan Penyegerakan

Untuk menunjukkan bahawa isu itu berpunca daripada kekurangan penyegerakan, pertimbangkan kod berikut:

<code class="go">package main

import (
    "sync"
    "time"
)

func main() {
    mx := new(sync.Mutex)
    i := 1
    go func() {
        for {
            mx.Lock()
            i++
            mx.Unlock()
        }
    }()
    <-time.After(1 * time.Second)
    mx.Lock()
    println(i)
    mx.Unlock()
}</code>
Salin selepas log masuk

Dalam kes ini, output bukan lagi 1, tetapi jumlah yang besar, seperti yang dijangkakan. Penyegerakan.Mutex menyediakan penyegerakan dan memastikan kedua-dua goroutine mengakses i secara terkawal, membenarkan goroutine menambah i dan membuat perubahan kelihatan kepada rutin utama.

Atas ialah kandungan terperinci Mengapa Goroutine Saya Menambah Pembolehubah Menghasilkan Keputusan Yang Tidak Dijangka?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
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