Mam pewne problemy z następującego kodu:Najlepszy sposób korzystania z funkcji sync.WaitGroup zewnętrznego
package main
import (
"fmt"
"sync"
)
// This program should go to 11, but sometimes it only prints 1 to 10.
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(2)
go Print(ch, wg) //
go func(){
for i := 1; i <= 11; i++ {
ch <- i
}
close(ch)
defer wg.Done()
}()
wg.Wait() //deadlock here
}
// Print prints all numbers sent on the channel.
// The function returns when the channel is closed.
func Print(ch <-chan int, wg sync.WaitGroup) {
for n := range ch { // reads from channel until it's closed
fmt.Println(n)
}
defer wg.Done()
}
dostaję impasu w określonym miejscu. Próbowałem ustawić wg.Add(1)
zamiast 2 i rozwiązuje mój problem. Jestem przekonany, że nie udało mi się wysłać kanału jako argumentu do funkcji Printer
. Czy jest jakiś sposób na zrobienie tego? W przeciwnym razie rozwiązanie mojego problemu jest zastąpienie linii go Print(ch, wg)
z:
go func() {
Print(ch)
defer wg.Done()
}
i zmiany funkcji Printer
do:
func Print(ch <-chan int) {
for n := range ch { // reads from channel until it's closed
fmt.Println(n)
}
}
Co jest najlepszym rozwiązaniem?
Got to, ja nie wiem, co potrzebne, aby być adres wysłane do 'Print' zamiast do samej' WaitGroup'. Zgadzam się, że metoda nie musi wiedzieć o 'WaitGroup', ale przypuśćmy, że i tak chcę. Co zatem robi gwiazda? Czy wybiera on RZECZYWISTY 'WaitGrooup', który zdefiniowałem w' main'? I dlaczego ten nie jest kopią? – Sahand
'' sync.WaitGroup' informuje kompilator, który ma mieć wskaźnik do 'WaitGroup' zamiast' WaitGroup'. Tak więc kompilator oczekuje, że wywołasz metodę, podając jej adres, stąd '& wg'. – Elwinar
Nie myśl, że możesz usunąć grupę roboczą drukowania jako główną, która mogłaby się przedawnić, zanim ostatnia wartość zostanie wydrukowana, jeśli oczekiwałeś na zakończenie nadawcy. Ponadto, nie ma powodu, aby zakończyć funkcję z opóźnieniem wg.Done(), odradzam w zasadzie oznacza, uruchom to na końcu. upuść odroczenie –