Код вернется с ошибкой, если вы не создадите буферные каналы по причине того, что канал закрыт до того, как все значения отправлены на него.
Не закрывайте каналы и дождитесь завершения процедур go.Если вы хотите закрыть каналы, закройте, когда все значения, отправленные по каналу, будут получены внутри подпрограммы приема приемника.
fmt.Println("testAsyncFunc2")
for i :=0; i < 10; i++ {
wg.Add(1)
go sender3(ch, i)
}
receiver3(ch)
close(ch) // this will close the channels before all the values sent on it will be received.
wg.Wait()
Еще одна вещь, которую вы заметили, вы увеличили счетчик группы ожидания до 10, пока выуменьшение счетчика после запуска подпрограммы go внутри цикла for, что неправильно.Вы должны уменьшить счетчик группы ожидания внутри подпрограммы отправителя, когда она завершит свое выполнение.
func sender(ch chan int, int){
defer wg.Done()
}
В цикле for условие выбора по умолчанию будет выполняться до получения всех значений, отправленных на канал, поэтомувсе отправленные значения не будут распечатаны.Поскольку цикл вернется, когда на канале не будет отправлено значение.
func receiver3(ch chan int) {
for {
select {
case <-ch:
fmt.Println(<-ch)
default: // this condition will run when value is not available on the channel.
fmt.Println("Done...")
return
}
}
}
Создайте подпрограмму go, чтобы закрыть канал и дождаться завершения подпрограмм отправителя go.Поэтому нижеприведенный код будет ожидать завершения всех ваших подпрограмм go для отправки значений по каналам, а затем закроет канал:
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
ch := make(chan int)
fmt.Println("testAsyncFunc2")
for i := 0; i < 10; i++ {
wg.Add(1)
go sender(ch, i)
}
receiver3(ch)
go func() {
defer close(ch)
wg.Wait()
}()
}
func receiver3(ch <-chan int) {
for i := 0; i < 10; i++ {
select {
case value, ok := <-ch:
if !ok {
ch = nil
}
fmt.Println(value)
}
if ch == nil {
break
}
}
}
func sender(ch chan int, i int) {
defer wg.Done()
ch <- i
}
Выход
testAsyncFunc2
9
0
1
2
3
4
5
6
7
8
Рабочий код на игровая площадка Go