4.2、Golang 并发编程-channel
Go 提供了一种通道机制,用于 goroutine 之间共享数据
通道需要指定数据类型
通道分类:
无缓冲通道 同步通讯
缓冲通道 异步通讯
语法
// 整型无缓冲通道,默认零值 Unbuffered := make(chan int) // 整型缓冲通道 buffered := make(chan int, 10)
通道数据交换
channel := make(chan string, 5) // 将值发送到通道 channel <- "hello" // 从通道接收值 data := <- channel
通道的发送和接收特性
同一通道,发送操作之间是互斥的,接收操作之间也是互斥的
发送操作和接收操作中对元素值的处理都是不可分割的
发送操作在完全完成之前会被阻塞,接收操作也是如此
示例
package main import ( "fmt" "math/rand" "time" ) // 创建一个int类型的通道 var value = make(chan int) func send() { // 向通道发送一个随机值 rand.Seed(time.Now().UnixNano()) v := rand.Intn(10) time.Sleep(time.Second * 3) value <- v } func main() { // 关闭通道 defer close(value) go send() fmt.Println("wait...") // 从通道接收值 v := <-value fmt.Printf("v: %v\n", v) }
Channel遍历
示例
package main import "fmt" var c = make(chan int) func main() { go func() { for i := 0; i < 2; i++ { c <- i } // 不关闭可能出现死锁 close(c) }() // 方式一 // for i := 0; i < 2; i++ { // v := <-c // fmt.Printf("v: %v\n", v) // } // 方式二 // for v := range c { // fmt.Printf("v: %v\n", v) // } // 方式三 for { v, ok := <-c if ok { fmt.Printf("v: %v\n", v) } else { break } } }