说明:
1.ch<-i 阻塞等待for range准备好。
2.for range也阻塞等待ch<-i输入数据。
3.end channel等待for range结束。
方式一:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
var ch chan int // 未初始化,值为 nil
end := make(chan struct{})
ch = make(chan int)
for i := 0; i < 3; i++ {
wg.Add(1)
go func(i int, group *sync.WaitGroup) {
defer group.Done()
ch <- i
}(i, &wg)
}
go func() {
time.Sleep(3*time.Second)
fmt.Println("start range")
for v := range ch {
fmt.Println("range ing")
fmt.Println(v)
}
end <- struct{}{}
}()
wg.Wait()
close(ch)
<-end
}
方式二:
然而并没有panic,因为主main已经结束,goroutine读取的还没结束。
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
var ch chan int // 未初始化,值为 nil
//end := make(chan struct{})
ch = make(chan int)
for i := 0; i < 3; i++ {
wg.Add(1)
go func(i int, group *sync.WaitGroup) {
defer group.Done()
ch <- i
}(i, &wg)
}
go func() {
time.Sleep(3*time.Second)
fmt.Println("start range")
for v := range ch {
fmt.Println("range ing")
fmt.Println(v)
}
//end <- struct{}{}
}()
wg.Wait()
time.Sleep(3*time.Second)
//close(ch)
//<-end
}
网友评论