2014-12-04 3 views
4

Интересно, почему нам нужно запустить wg.Wait() в goroutineGo WaitGroup с goroutine

// This one works as expected... 
func main() { 
    var wg sync.WaitGroup 
    for i:=0; i<5; i++ { 
     wg.Add(1) 
     go func() { 
      defer wg.Done() 
     }() 
     time.Sleep(time.Second) 
    } 
    go func() { 
     wg.Wait() 
    }() 
} 

в Но это один никогда не заканчивается ждать вечно

func main() { 
    var wg sync.WaitGroup 
    for i:=0; i<5; i++ { 
     wg.Add(1) 
     go func() { 
      defer wg.Done() 
     }() 
     time.Sleep(time.Second) 
    } 
    wg.Wait() 
} 

Может кто-нибудь объяснить, почему я должен ждать в другом goroutine ?

Спасибо!

+1

Уверены ли вы? Я бы предположил, что что-то сломано в не показанной части кода, тем более, что первая версия не ждет ИМХО. – Volker

+0

Мой код на самом деле делает намного больше, и он снова использует свои собственные goroutines. Я получаю этот шаблон от https://github.com/rakyll/coop/blob/master/coop.go#L85 –

+0

Здесь она выполняет 'wg.Wait()' в goroutine. –

ответ

1

Почему нам нужно запустить wg.Wait() в goroutine?

В примере вы упоминаете (coop/blob/master/coop.go#L85), ожидание в goroutine, чтобы вернуться сразу канал, который будет показывать, когда все остальные goroutines закончили. Таковы goroutines быть начаты:

for _, fn := range fns { 
    go func(f func()) { 
     f() 
     wg.Done() 
    }(fn) 
} 

Они упоминают о завершении через var wg sync.WaitGroup.
что WaitGroup установлен ждать правого ряда goroutines закончить:

wg.Add(len(fns)) 

Ожидание делается в goroutine, потому что это, в свою очередь сигнал глобального завершения на канал:

go func() { 
    wg.Wait() 
    doneSig(ch, true) 
}() 

Но канал немедленно возвращается.

ch := make(chan bool, 1) 
... 
return ch 

Вот почему Wait выполняется асинхронно: вы не хотите ждать в этой функции. Вам просто нужен канал.