基础篇简单了介绍Channel&Goroutine的基本使用方法
接下来就是实际应用的问题了
实际例子上可能会有1-N个不等的chaneel
这时候就需要使用专门给channel使用的switch case,叫做Select
Select有几个地方要注意
语法请看综合范例2有演示
使用Goroutine最重要的
不要对routing的输出顺序以及时间做出假设
举个简单的例子,只要印出123
func main() {
go func() {
log.Println("123")
}()
//没有暂停1秒钟让另一个routing准备好,有可能程序会直接结束而不会输出任何东西
time.Sleep(1 * time.Second)
}
可以试试看把time.Sleep(1 * time.Second)给Remark,基本上是不会输出任何东西,至少我是没有成功过
因为Goroutine有极大的可能在main function执行完时而还没有开始执行
所以Goroutine的closure就会什麽都没有执行就结束了
这是最重要也是最难的部分
在使用Channel的时候最常要注意的事情就是deaklock
因为会deadlock的案例实在不胜枚举,这边会提供给大家正确的做法,会有deadlock的情境会尽量提到
基础篇有提到UnBuffered Channel有着同步的特性
这种channel的两端会等待着写入与读取,而且因为没有Buffer,所以Channel的两端会同步资料
func main() {
ch := make(chan bool)
go func() {
ch <- true
}()
// 虽然没有time.Sleep等待goroutine执行
// 但最後有一个<-ch一直读取channel
// 所以可以看到Print true
log.Println(<-ch)
}
可以使用for range方法读取里面的资料
func main() {
ch := make(chan int, 10)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
}()
for value := range ch {
log.Println(value)
}
}
从channel利用for loop读取资料,可以搭配基础篇服用
make channel的那一行可以加上cap玩看看,马上就能知道UnBuffered & Buffered的差异
close(ch)那段最重要,可以试试看remark的结果,保证deadlock
func main() {
ch := make(chan int) // 可以加上cap,一样可以正常跑程序,而且可以看出UnBuffered & Buffered的差异
go func() {
for i := 0; i < 10; i++ {
log.Println("Send value", i)
ch <- i
}
close(ch) // close channel很重要,没有闭关的话,另一端一直在读取,而没有资料写入,就会产生deadlock
}()
for {
val, ok := <-ch
if ok {
log.Println("Receive value", val)
} else {
break
}
}
}
执行这段程序码有个重点
不要预期routing的执行时间,先後顺序,一切的假设都不要有
for loop的部分是要一直读取channel value
而当x==20时就会触发事件s<-str
select接收到s channel的value时就会执行该case,跳出带有LOOP tag的for loop
func main() {
str := "stop"
c := make(chan int)
s := make(chan string)
for i := 0; i < 50; i++ {
go func(x int) {
if x == 20 {
log.Println("goroutine will stop")
s <- str
} else {
log.Println("Send value", x)
c <- x
}
}(i)
}
LOOP:
for {
select {
case v, ok := <-c:
if ok {
log.Println("Select value", v)
}
case str := <-s:
log.Println(str)
break LOOP
default:
log.Println("wait")
}
}
}
在使用Goroutine&channel的时候要注意的地方大致可以归类在以下几点
然後要自己写一遍,多deadlock几次到差点想把笔电一分为二的时候你就会了(误
其他还有Package sync & Package runtime,就等下一篇吧
<<: 软件保障成熟度模型(Software Assurance Maturity Model :SAMM)
「查询Gamil资讯」API 实作完成,那就可以部署上线测试啦。 今日要点: 》部署 API 》呼...
今天来进入下一个动画,这次的主题是描述湾熊(自创角色)的日常,那麽,我们开始吧! 1. 2. 3. ...
原始题目 You are given a large integer represented as ...
人的科技文明发展始终来自於人性 在科技的发展与技术的发展之下,在很多的领域都有许多的应用,甚至因为科...
现在再加上一点音效做装饰,先给一个背景音乐,直接在Hierarchy按右键开启Audio->A...