Sobes.tech
Senior

func main() { c := make(chan int, 1000) for i := 0; i < 100; i++ { go foo(c) } sum := 0 for r := range c { sum += r } fmt.Println(sum) } func foo(c chan int) { r := rand.Int() for i := 0; i < r; i++ { c <- r } } --- func main() { c := make(chan int, 1000) var wg sync.WaitGroup wg.Add(100) for i := 0; i < 100; i++ { go func() { defer wg.Done() foo(c) }() } go func() { wg.Wait() close(c) }() sum := 0 for r := range c { sum += r } // // fmt.Println(sum) } func foo(c chan int) { r := rand.Int() for i := 0; i < r; i++ { c <- r } }

sobes.tech AI

Απάντηση από AI

Στην πρώτη έκδοση του κώδικα υπάρχει ένα πρόβλημα: ο βρόχος for r := range c θα περιμένει επ' αόριστον επειδή το κανάλι c ποτέ δεν κλείνει. Αυτό θα προκαλέσει το πάγωμα του προγράμματος.

Στη δεύτερη έκδοση, προστέθηκε το sync.WaitGroup για να περιμένει την ολοκλήρωση όλων των goroutines, και μετά κλείνει το κανάλι c. Αυτό επιτρέπει την σωστή έξοδο από τον βρόχο ανάγνωσης του καναλιού.

Βασικά σημεία:

  • Χρήση του sync.WaitGroup για την παρακολούθηση της ολοκλήρωσης όλων των goroutines.
  • Κλείσιμο του καναλιού αφού όλες οι goroutines ολοκληρώσουν την εγγραφή.
  • Ο βρόχος for r := range c τερματίζει όταν το κανάλι κλείσει.

Παραδείγματα διορθωμένου κώδικα:

group := sync.WaitGroup{}
group.Add(100)
for i := 0; i < 100; i++ {
    go func() {
        defer group.Done()
        foo(c)
    }()
}
go func() {
    group.Wait()
    close(c)
}()

sum := 0
for r := range c {
    sum += r
}