定义
概念定义
channel是一种用于goroutine之间进行通信和同步的机制。它提供了一种安全、简单的方式来传递数据
代码定义
func main() {
// 定义有缓冲通道
chan1 := make(chan int, 10)
// 定义无缓冲通道
chan2 := make(chan int)
}
有缓冲通道
有缓冲channel:使用make函数的第二个参数指定缓冲大小,缓冲区未满时,发送操作不会阻塞。
package main
import (
"fmt"
"time"
)
func main() {
// 定义有缓冲通道
chan1 := make(chan int, 2)
go func() {
for i := 0; i < 4; i++ {
chan1 <- i
fmt.Println("chan1 写入数据", i)
}
close(chan1)
}()
for i := 0; i < 10; i++ {
time.Sleep(1 * time.Second)
fmt.Println("第", i, "秒")
}
}
-----------------运行结果----------------------
chan1 写入数据 0
chan1 写入数据 1
第 0 秒
第 1 秒
第 2 秒
第 3 秒
第 4 秒
第 5 秒
第 6 秒
第 7 秒
第 8 秒
第 9 秒
无缓冲通道
无缓冲channel:发送操作会阻塞直到有接收操作匹配。
package main
import (
"fmt"
"time"
)
func main() {
// 定义有缓冲通道
chan1 := make(chan int)
go func() {
for i := 0; i < 4; i++ {
chan1 <- i
fmt.Println("chan1 写入数据", i)
}
close(chan1)
}()
for i := 0; i < 10; i++ {
time.Sleep(1 * time.Second)
fmt.Println("第", i, "秒")
}
s := <-chan1
fmt.Println("读出的数据是", s)
}
-----------------运行结果----------------------
第 0 秒
第 1 秒
第 2 秒
第 3 秒
第 4 秒
第 5 秒
第 6 秒
第 7 秒
第 8 秒
第 9 秒
读出的数据是 0
chan1 写入数据 0
select关键字
select语句用于处理多个channel的操作,可以同时等待多个channel的通信操作。当通道内部一直无数据写入,则会阻塞整个流程
package main
import (
"fmt"
)
func main() {
// 定义有缓冲通道
chan1 := make(chan int)
chan2 := make(chan int, 10)
go func() {
for i := 0; i < 4; i++ {
chan1 <- i
chan2 <- i
fmt.Println("chan1/2 写入数据", i)
}
close(chan1)
}()
select {
case v := <-chan1:
fmt.Println("chan1 读取数据", v)
case v := <-chan2:
fmt.Println("chan2 读取数据", v)
}
}
-----------------运行结果----------------------
chan1/2 写入数据 0
chan1 读取数据 0
注意事项
- 在使用完毕之后,切记要关闭channel,否则会导致死锁或是资源泄漏
- 多次关闭channel会引发panic:只能关闭一次channel。
- 向已关闭的channel发送数据会引发panic。
- 从已关闭的channel接收数据不会引发panic,但会返回零值。