Channels 是 Go 语言中的一个核心特性,它们为 Go Routines 之间的通信提供了一种安全、方便的方式。
什么是 Channel?
Channel 是一个可以用于并发 Go Routines 之间传递类型化数据的通信机制。你可以把它想象成一个可以发送和接收值的管道。
如何创建 Channel?
创建 Channel 使用 make
函数和 chan
关键字:
ch := make(chan int) // 创建一个可以发送和接收 int 类型数据的 Channel
如何发送和接收数据?
向 Channel 发送数据和从 Channel 接收数据,使用 <-
运算符:
ch <- v // 发送 v 到 Channel ch
v := <-ch // 从 Channel ch 接收数据,并赋值给 v
一个简单的例子
下面的程序演示了如何使用 Channel 在两个 Go Routine 之间传递数据:
package main
import "fmt"
func worker(done chan bool) {
fmt.Print("working...")
// 模拟一些工作
for i := 0; i < 1000000000; i++ {
}
fmt.Println("done")
// 向 Channel 中发送一个值,表示工作已经完成
done <- true
}
func main() {
// 创建一个新的 Channel
done := make(chan bool)
// 开启一个新的 Go Routine
go worker(done)
// 从 Channel 中接收数据,如果 Channel 还没有数据,会阻塞,直到有数据为止
<-done
}
在这个例子中,我们创建了一个 bool
类型的 Channel done
,然后在一个新的 Go Routine 中执行 worker
函数。worker
函数完成工作后,会向 done
Channel 发送一个值。在 main
函数中,我们等待从 done
Channel 中接收一个值。这确保了 main
函数会等待 worker
Go Routine 完成工作。
Channel 的关闭
发送者可以关闭一个 Channel 来表示没有更多的值会被发送。接收者可以使用一个额外的接收参数来检查 Channel 是否已经关闭:
v, ok := <-ch
在上述代码中,如果 ok
为 true
,则表示 v
是从 Channel 中接收的值。如果 ok
为 false
,则表示 Channel 已经关闭,并且没有更多的值可接收。
总的来说,Channel 是一种强大的工具,用于在 Go Routines 之间安全地传递数据。虽然 Go Routines 是并发执行的,但是 Channel 可以确保数据的同步传递:数据的发送和接收是原子操作,同时只有一个 Go Routine 可以发送或接收数据。这使得使用 Channel 编写并发程序变得更加简单和安全。
推荐阅读:
https://mp.weixin.qq.com/s/dV2JzXfgjDdCmWRmE0glDA
https://mp.weixin.qq.com/s/an83QZOWXHqll3SGPYTL5g
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。