Go 的 channel 在实际项目中是怎么使用呢? channel 会有有缓冲和无缓冲两种类型,无缓冲的可以简单使用让两个 goroutine 数据同步通信。另外一种场景是对某个 object,使用 channel 作为其属性之一,那么待channel阻塞时则表明条件未满足,则需要等待其他数据结果返回。
本文列举几类常见的 channel 使用场景。
读写
package main
import (
"fmt"
"time"
)
func WriteData(intChan chan int) {
for i:=1;i<=50;i++{
intChan<-i
fmt.Println("写:",i)
time.Sleep(time.Millisecond*100)
}
close(intChan) //写完后关闭管道
}
func ReadData(intChan chan int,exitChan chan bool) {
for{
v,ok:=<-intChan
if !ok{
fmt.Println("读取完毕")
break
}
fmt.Println("读:",v)
}
//设置全局标志 告诉main 读取完毕了 main主线程可以关闭了
exitChan<-true
close(exitChan)
}
func main() {
intChan :=make(chan int,50)
exitChan:=make(chan bool,1)
go WriteData(intChan)
go ReadData(intChan,exitChan)
//阻塞主线程
for ok:=range exitChan{
fmt.Println(ok)
}
}
管道实现定时通知
func Notice(d time.Duration) chan bool {
c := make(chan bool, 1)
go func() {
time.Sleep(d) //定时
c <- true
}()
close(c)
return c
}
func main() {
log.Println("one")
<-Notice(time.Second) //管道没有写则阻塞
log.Println("tow")
<-Notice(time.Second)
log.Println("three")
}
管道实现互斥锁
package main
import (
"log"
"time"
)
var counter=0
func Increase1000(id int,done chan bool,mutex chan bool){
for i:=0;i<1000;i++{
mutex<-true //加锁
counter+=1
time.Sleep(time.Microsecond)
<-mutex //解锁
}
done<-true
}
func main() {
mutex,done:=make(chan bool,1),make(chan bool)
go Increase1000(1,done,mutex)
go Increase1000(2,done,mutex)
<-done;<-done
log.Println(counter)
}