Middle+
Mit fog a program futtatásakor megjelenni: 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) // Munka szimuláció }() } wg.Wait() fmt.Println(len(counter)) }
sobes.tech MI
Válasz az MI-től
A program adatversenyt tart, amikor több goroutine ír a counter szeletbe szinkronizálás nélkül. Ez kiszámíthatatlan viselkedéshez vezet.
Mi történik:
- Létrejön egy
counterszelet 0 hosszúsággal és 1000 kapacitással. - 1000 goroutine indul, mindegyik megpróbálja hozzáadni az
iértékét a szelethez. - Az
appendművelet nem szálbiztos, több goroutine módosítja a szeletet egyidejűleg. - Az adatverseny miatt adatvesztés, a szelet sérülése vagy pánik fordulhat elő.
A végén:
- A
len(counter)értéke lehet kevesebb, mint 1000, mivel néhány bejegyzés elveszhet. - Pánik vagy helytelen kimenet fordulhat elő.
A helyes megközelítés mutex vagy csatorna használata a hozzáférés szinkronizálására:
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)
}
Vagy szálbiztos adatstruktúrák használata.