Sobes.tech
Middle+

Ce va fi afișat la rularea programului: func main() { counter := make([]int, 0, 1000) var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go func() { defer wg.Done() counter = append(counter, i) time.Sleep(10 * time.Millisecond) // Simulare de lucru }() } wg.Wait() fmt.Println(len(counter)) }

sobes.tech AI

Răspuns de la AI

Programul conține o cursă de date atunci când scrie în segmentul counter din mai multe gorutine fără sincronizare. Acest lucru duce la comportament imprevizibil.

Ce se întâmplă:

  • Se creează un segment counter cu lungimea 0 și capacitatea de 1000.
  • Se pornesc 1000 de gorutine, fiecare încercând să adauge valoarea i în segment.
  • Operația append nu este sigură pentru fire, mai multe gorutine modifică segmentul în același timp.
  • Din cauza cursei de date, pot apărea pierderi de date, corupție a segmentului sau panică.

La final:

  • Valoarea len(counter) poate fi mai mică de 1000, deoarece unele înregistrări pot fi pierdute.
  • Poate apărea o panică sau o ieșire incorectă.

Abordarea corectă este să folosiți un mutex sau un canal pentru a sincroniza accesul la segment:

var mu sync.Mutex

for i := 0; i < 1000; i++ {
    wg.Add(1)
    go func(val int) {
        defer wg.Done()
        mu.Lock()
        counter = append(counter, val)
        mu.Unlock()
        time.Sleep(10 * time.Millisecond)
    }(i)
}

Sau să folosiți structuri de date sigure pentru fire.