go Channel原理
warning:
这篇文章距离上次修改已过183天,其中的内容可能已经有所变动。
在Go语言中,channel是一种内置的数据类型,可以用于安全地进行并发编程。它主要用于goroutine之间的通信。
在上一篇文章中,我们讨论了channel的创建和使用。在这篇文章中,我们将深入探讨channel的工作原理。
- channel的创建
在Go中,我们可以使用内建的make函数来创建一个channel。例如,我们可以创建一个用于int类型数据传输的channel:
c := make(chan int)
- channel的发送和接收
我们可以使用操作符<-来进行数据的发送和接收。如果我们在发送操作符左边使用chan类型的变量,那么这就是一个发送操作。如果我们在接收操作符右边使用chan类型的变量,那么这就是一个接收操作。
// 发送操作
c <- 10
// 接收操作
x := <-c
- channel的关闭
我们可以使用close函数来关闭一个channel。当一个channel被关闭后,我们不能再往这个channel发送数据,但我们可以继续从这个channel接收数据直到所有被发送的数据都被接收。
close(c)
- channel的种类
Go语言的channel有以下几种类型:
- 无缓冲的channel:这种类型的channel不会存储任何数据,发送和接收必须是同时进行的。
c := make(chan int)
- 有缓冲的channel:这种类型的channel可以存储一定数量的数据。
c := make(chan int, 10)
- channel的示例
下面是一个使用channel的简单例子:
package main
import "fmt"
func sum(a, b int, c chan int) {
c <- a + b
}
func main() {
c := make(chan int)
go sum(3, 4, c)
fmt.Println(<-c)
}
在这个例子中,我们创建了一个无缓冲的channel c,然后我们在一个goroutine中调用sum函数,并将channel c作为参数传递。sum函数将a和b的和发送到channel c。在main函数中,我们从channel c接收数据并打印。
- select语句
select语句可以用来处理多个channel上的发送和接收操作。当select语句被执行时,它会阻塞,直到一个可运行的case出现。如果多个case都可以运行,select会随机选择一个执行。
package main
import "fmt"
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
}()
fibonacci(c, quit)
}
在这个例子中,我们创建了一个无缓冲的channel c和quit。然后我们在一个goroutine中调用fibonacci函数,并将channel c和quit作为参数传递。fibonacci函数将Fibonacci数列的数字
评论已关闭