122 lines
2.5 KiB
Go
122 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// ===================== 一、Channel 类型系统 =====================
|
|
// producer 只写通道 生产者
|
|
func producer(ch chan<- int) {
|
|
defer close(ch) // 延迟关闭,确保数据发送完毕
|
|
for i := 1; i <= 2; i++ {
|
|
ch <- i * 10
|
|
}
|
|
}
|
|
|
|
// consumer 只读通道 消费者
|
|
func consumer(ch <-chan int) {
|
|
for data := range ch {
|
|
fmt.Printf("消费数据:%d\n", data)
|
|
}
|
|
}
|
|
|
|
// ===================== 二、Channel 缓冲策略 =====================
|
|
func bufferDemo() {
|
|
fmt.Println("\n===== 无缓冲通道(同步通信)=====")
|
|
unbufCh := make(chan string)
|
|
go func() {
|
|
unbufCh <- "同步通道数据"
|
|
}()
|
|
fmt.Println(<-unbufCh)
|
|
|
|
fmt.Println("\n===== 有缓冲通道(异步通信)=====")
|
|
bufCh := make(chan int, 3)
|
|
bufCh <- 1
|
|
bufCh <- 2
|
|
// 监控缓冲状态
|
|
fmt.Printf("已缓存数据:%d,总缓冲容量:%d\n", len(bufCh), cap(bufCh))
|
|
close(bufCh)
|
|
|
|
for v := range bufCh {
|
|
fmt.Println("异步数据:", v)
|
|
}
|
|
}
|
|
|
|
// ===================== 三、Channel 安全关闭 =====================
|
|
func closeDemo() {
|
|
fmt.Println("\n===== 通道安全关闭演示=====")
|
|
ch := make(chan int, 2)
|
|
// 保证通道仅关闭一次
|
|
var closeOnce sync.Once
|
|
|
|
go func() {
|
|
closeOnce.Do(func() {
|
|
ch <- 100
|
|
ch <- 200
|
|
close(ch)
|
|
fmt.Println("通道已安全关闭")
|
|
})
|
|
}()
|
|
|
|
// 安全读取数据
|
|
for {
|
|
val, ok := <-ch
|
|
if !ok {
|
|
fmt.Println("通道关闭,读取结束")
|
|
break
|
|
}
|
|
fmt.Printf("读取值:%d\n", val)
|
|
}
|
|
}
|
|
|
|
// ===================== 四、Channel 高级用法 =====================
|
|
func advancedDemo() {
|
|
fmt.Println("\n===== select 多路复用=====")
|
|
ch1, ch2 := make(chan string), make(chan string)
|
|
|
|
// 模拟异步任务
|
|
go func() {
|
|
time.Sleep(100 * time.Millisecond)
|
|
ch1 <- "任务1执行完成"
|
|
}()
|
|
go func() {
|
|
time.Sleep(200 * time.Millisecond)
|
|
ch2 <- "任务2执行完成"
|
|
}()
|
|
|
|
// 监听多个通道
|
|
for i := 0; i < 2; i++ {
|
|
select {
|
|
case msg := <-ch1:
|
|
fmt.Println(msg)
|
|
case msg := <-ch2:
|
|
fmt.Println(msg)
|
|
}
|
|
}
|
|
|
|
// 非阻塞读取
|
|
fmt.Println("\n===== 非阻塞通道读取=====")
|
|
ch := make(chan int, 1)
|
|
select {
|
|
case val := <-ch:
|
|
fmt.Println("读取到数据:", val)
|
|
default:
|
|
fmt.Println("通道暂无数据,非阻塞跳过")
|
|
}
|
|
}
|
|
|
|
// ===================== 主函数 =====================
|
|
func main() {
|
|
fmt.Println("===== 一、Channel 类型系统演示=====")
|
|
ch := make(chan int)
|
|
go producer(ch)
|
|
consumer(ch)
|
|
|
|
// 执行所有演示
|
|
bufferDemo()
|
|
closeDemo()
|
|
advancedDemo()
|
|
}
|