【发布时间】:2018-11-30 05:33:57
【问题描述】:
上下文:https://tour.golang.org/concurrency/5
大家好,我正在按照上面的链接学习 Go。
描述说“如果有多个准备好,它会随机选择一个。” 但是,在使主程序等待 2 秒后,在调用 func fibonacci 之前。 2 秒后通道应如下所示: c: 10 次调用以从渠道获取价值 退出:0
在我看来,两个频道都准备好了。如果“如果多个都准备好了,它会随机选择一个”为真,那么斐波那契案例中的第一个调用将有 50% 的机会从退出通道中获得 0。然而,事实并非如此。在退出之前,所有 10 个数字都会被打印出来。因此,看起来选择不是随机的。我错过了什么吗?
package main
import "fmt"
import "time"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x:
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
time.Sleep(2 * time.Second)
fibonacci(c, quit)
}
另外,下一页: https://tour.golang.org/concurrency/6
看起来默认代码应该打印出任何一个勾号。或繁荣!在 500 毫秒。然而,只有BOOM!总是打印出来的。如果我将默认时间从 50 更改为 55,则刻度和 BOOM 都会被打印。为什么是这样?在选择中,After 是否优先于 Tick?
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(55 * time.Millisecond)
}
}
}
【问题讨论】:
-
为什么你认为两个渠道都准备好了?
quit还没有准备好,因为没有 goroutine 正在写入。 -
我相信它已经准备好了,因为主例程已经等待了 2 秒,编辑:这应该足以让 go func 例程完成......对吗?
-
不,goroutine 无法完成,因为它正在等待有人将值写入
c。