无缓冲通道,一发送对应一接收,接收使用循环获取通道里的值,接收完成时退出循环,以避免阻塞。
for ... rang和for{}都可以获取所有通道值,等价的,都可以使用break退出。
使用了sync.WaitGroup来控制并发完成才能退出主gorouting,不然要使用time.sleep()方法等待完成。time.sleep()不好控制时间,因为你不确定真正完成时间。
package main
import (
"fmt"
"sync"
"time"
)
var wg sync.WaitGroup
func main() {
wg.Add(2)
ch := make(chan int)
go sender(ch) // sender goroutine
go recver(ch) // recver goroutine
//time.Sleep(1e9)
wg.Wait()
}
func sender(ch chan int) {
defer wg.Done()
for i := 0; i < 10; i++ {
time.Sleep(time.Second * 2)
fmt.Println("sender:", i)
ch <- i
}
}
func recver(ch chan int) {
defer wg.Done()
//var recv string
//for {
// recv = <-ch
// fmt.Println(recv)
//}
i := 0
for a := range ch {
fmt.Println("reciver:", a)
i++
if i == 10 {
break
}
}
//for {
// v, ok := <-ch
// if ok {
// fmt.Println(v, ok)
// if v == "tuner" {
// break
// }
// }
//}
}
输出:
PS F:\gopractise> go run main.go
sender: 0
reciver: 0
sender: 1
reciver: 1
sender: 2
reciver: 2
sender: 3
reciver: 3
sender: 4
reciver: 4
sender: 5
reciver: 5
sender: 6
reciver: 6
sender: 7
reciver: 7
sender: 8
reciver: 8
sender: 9
reciver: 9
PS F:\gopractise>