初学golang通道尝试了如下代码:
```
package main
import (
"fmt"
"time"
)
type Sender chan<- int
type Receiver <-chan int
func main() {
var myChannel = make(chan int, (0))
var number = 6
go func() {
var sender Sender = myChannel
sender <- number // 1
sender <- number // 2
fmt.Println("Sent!") //5
}()
go func() {
var receiver Receiver = myChannel
fmt.Println("Received!", <-receiver) //3
}()
go func() {
var receiver Receiver = myChannel
fmt.Println("Received!", <-receiver) //4
}()
time.Sleep(time.Second)
}
```
定义了一个非缓存myChannel后,在1处应该阻塞了,然后执行了3处,这时候通道里没数据应该执行2处之后阻塞了再执行4处,最后回到5处。
但实际结果是:
Received! 6
Sent!
Received! 6
这是为什么啊?有大神给解释一下吗
这个当然不会阻塞了。
因为这三个函数是并行执行的啊。
```
go func() {
var sender Sender = myChannel
sender <- number // 1
sender <- number // 2
fmt.Println("Sent!") //5
}()
go func() {
var receiver Receiver = myChannel
fmt.Println("Received!", <-receiver) //3
}()
go func() {
var receiver Receiver = myChannel
fmt.Println("Received!", <-receiver) //4
}()
```
他们三个是没有先后顺序的,在1写入数据之前,3和4被阻塞。当1执行完sender <- number // 1 的时候2确实会阻塞,但是只是阻塞当前协程。
后面那两个3和4还继续执行,这时候3或者4从channel中取出number。然后 sender <- number // 2就不阻塞了,继续执行,将数据写入chanel。
这时候3或4中剩下的那个没有取到数据而被阻塞的协程就会继续执行,然年后将2写入的数据取出。
#1
更多评论
哦哦大致理解,之前以为2执行之后应该执行3或者4后才输出"Sent!",然后我发现如果2之后不sleep的话,“Sent!”出现的顺序是不确定,原因是执行2之后,345是协程竞争关系了,所以它们三个谁都可能先执行。
#2