通道使用语法
理论知识就略过了
发送和接收
package main
import (
"fmt"
)
var ch1 chan int
func main() {
// 创建只能传递 int 类型值的通道
ch1 = make(chan int)
// chan int 0xc00005e060
//fmt.Printf("%T %v\n", ch1, ch1)
// 子 goroutine
go wirteData()
// 主 goroutine 读取通道 ch1 当中的数据
data := <-ch1
fmt.Println("主 goroutine 从通道 ch1 读取的数据:",data)
}
// 子 goroutine
func wirteData() {
fmt.Println("子 goroutine 向通道 ch1 写入数据")
ch1 <- 11111
fmt.Println("子 goroutine 执行结束。。")
}
执行结果
子 goroutine 向通道 ch1 写入数据
子 goroutine 执行结束。。
主 goroutine 从通道 ch1 读取的数据: 11111
分析
Channel通道在使用的时候,有以下几个注意点:
- 1.用于goroutine,传递消息的。
- 2.通道,每个都有相关联的数据类型, nil chan,不能使用,类似于nil map,不能直接存储键值对
- 3.使用通道传递数据:<- chan <- data,发送数据到通道。向通道中写数据 data <- chan,从通道中获取数据。从通道中读数据
- 4.阻塞: 发送数据:chan <- data,阻塞的,直到另一条goroutine,读取数据来解除阻塞 读取数据:data <- chan,也是阻塞的。直到另一条goroutine,写出数据解除阻塞。
- 5.本身channel就是同步的,意味着同一时间,只能有一条goroutine来操作。
关闭通道
package main
import (
"fmt"
"time"
)
var ch chan int
func main() {
ch = make(chan int)
// 子 goroutine 执行
go send()
// 循环向通道 ch 读取数据
for value := range ch {
fmt.Println("主 goroutine 读取通道 ch 的值:",value)
}
fmt.Println("运行结束")
}
func send() {
for i := 1; i < 10; i++ {
time.Sleep(1 * time.Second)
fmt.Println("子 goroutine 向通道 ch 写入:",i)
ch <- i
}
fmt.Println("关闭通道 ch ")
close(ch)
}
关闭运行结果
子 goroutine 向通道 ch 写入: 1
主 goroutine 读取通道 ch 的值: 1
子 goroutine 向通道 ch 写入: 2
主 goroutine 读取通道 ch 的值: 2
子 goroutine 向通道 ch 写入: 3
主 goroutine 读取通道 ch 的值: 3
子 goroutine 向通道 ch 写入: 4
主 goroutine 读取通道 ch 的值: 4
子 goroutine 向通道 ch 写入: 5
主 goroutine 读取通道 ch 的值: 5
子 goroutine 向通道 ch 写入: 6
主 goroutine 读取通道 ch 的值: 6
子 goroutine 向通道 ch 写入: 7
主 goroutine 读取通道 ch 的值: 7
子 goroutine 向通道 ch 写入: 8
主 goroutine 读取通道 ch 的值: 8
子 goroutine 向通道 ch 写入: 9
关闭通道 ch
主 goroutine 读取通道 ch 的值: 9
运行结束
通道关闭的意义
读和写需要完全对应,如果一直阻塞读,而不往通道去写,必然会造成死锁