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
}