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
}
}
}