有缓冲 channel
有缓冲 channel 是指带有一定存储空间的 channel,发送和接收操作不一定需要同步进行。当缓冲区未满时,发送操作会立即返回,并将数据存储在缓冲区中,而接收操作则会等待直到缓冲区中有数据可用。当缓冲区已满时,发送操作将被阻塞,直到缓冲区中有空闲位置可用。
以下是使用有缓冲 channel 进行通信的例子:
代码语言:javascript复制package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println("receiving", <-ch)
fmt.Println("receiving", <-ch)
}
在这个例子中,我们创建了一个带有 2 个存储空间的有缓冲 channel ch
,然后向 channel 中发送了两个数值,并在主 goroutine无缓冲 channel 是指在 channel 中只能存储一个值,即该 channel 的容量为 0。如果有 goroutine 向一个未被接收的无缓冲 channel 中发送值,那么该 goroutine 会一直阻塞,直到有另一个 goroutine 从该 channel 中接收该值。这种阻塞的机制使得 goroutine 的执行是同步的,即发送和接收操作在 channel 上是同步的。
下面是一个使用无缓冲 channel 的例子:
代码语言:javascript复制package main
import "fmt"
func main() {
c := make(chan int) // 创建一个无缓冲 channel
go func() {
fmt.Println("Start goroutine")
c <- 1 // 向 channel 发送值
fmt.Println("End goroutine")
}()
fmt.Println("Start main")
v := <-c // 从 channel 中接收值
fmt.Println("Received", v)
fmt.Println("End main")
}
输出结果为:
代码语言:javascript复制Start main
Start goroutine
Received 1
End main
End goroutine
在 main 函数中,先创建了一个无缓冲 channel c,并启动了一个新的 goroutine,该 goroutine 向 channel 中发送了值 1。然后,main 函数中的代码从 channel 中接收值,并将其打印出来。在这个过程中,main 函数会一直阻塞,直到从 channel 中接收到值。接着,goroutine 中的代码继续执行,将打印出 End goroutine。
由于无缓冲 channel 在发送和接收操作上是同步的,因此在这个例子中,Start goroutine 和 Start main 的输出顺序是不确定的。因为无缓冲 channel 保证了发送和接收操作的同步,所以这个例子中的输出结果是正确的,而不会出现类似数据竞争的问题。