我正在阅读Go的官方教程,很难理解频道和缓冲频道之间的区别。到教程的链接是https://tour.golang.org/concurrency/2和https://tour.golang.org/concurrency/3。
在频道教程中,c频道首先收到7,2,8之和为17,然后收到-9,4,0之和为-5。当从c中读取时,它首先以LIFO顺序输出5到x,然后从17输出到y:
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}(上述产出为-5 17 12)
在缓冲频道教程中,输出为12,按FIFO顺序:
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch)
fmt.Println(<-ch)
}他们为什么不一样?
发布于 2018-04-14 16:01:35
在您的第一个非缓冲信道示例中,chnnael c没有充当LIFO。
事实上,它之所以发生是因为go routines。go routines同时执行。
如果您调整代码以进行调试,则在发送到通道之前添加一行加总以打印和。
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
fmt.Println("slice:", s)
fmt.Println(sum)
c <- sum // send sum to c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:2], c)
go sum(s[2:4], c)
go sum(s[4:6], c)
x, y, z := <-c, <-c, <-c // receive from c
fmt.Println(x, y, z, x+y+z)
}产出如下:
slice: [4 0]
4
slice: [7 2]
9
slice: [8 -9]
-1
4 9 -1 12因此,您可以看到x接收通过通道发送的第一个号码。
此外,未缓冲信道直接将数据发送给接收方。
如果你想知道go中频道的架构,你可以看gophercon-2017。我觉得这个演讲很有帮助。
https://stackoverflow.com/questions/49832478
复制相似问题