Sobes.tech
Middle+

პროგრამა მუშაობისას რა გამოიტანს: 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) // სამუშაოს იმიტაცია }() } wg.Wait() fmt.Println(len(counter)) }

sobes.tech AI

პასუხი AI-სგან

პროგრამა შეიცავს მონაცემთა რბოლას, როდესაც რამდენიმე გორუტინიდან იწერება სეგმენტში counter სინქრონიზაციის გარეშე. ეს οδηγებს გაურკვეველ ქცევას.

რა ხდება:

  • შეიქმნება სეგმენტი counter სიგრძით 0 და მოცულობით 1000.
  • იწყება 1000 გორუტინი, თითოეული ცდილობს დაამატოს მნიშვნელობა i სეგმენტში.
  • ოპერაცია append არ არის ნაკადი-უსაფრთხო, რამდენიმე გორუტინი ერთდროულად იცვლის სეგმენტს.
  • მონაცემთა რბოლის გამო შეიძლება იყოს მონაცემთა დაკარგვა, სეგმენტის დაზიანება ან პანიკა.

დასასრულ:

  • მნიშვნელობა len(counter) შეიძლება იყოს ნაკლები 1000-ის, რადგან ზოგი ჩანაწერი შეიძლება დაკარგოს.
  • შეიძლება მოხდეს პანიკა ან არასწორი გამოტანა.

სწორი მიდგომაა mutex ან არხის გამოყენება სეგმენტზე წვდომის სინქრონიზაციისთვის:

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

ან გამოიყენეთ ნაკადი-უსაფრთხო მონაცემთა სტრუქტურები.