Channel
什么是chanel
用来连接并发的goroutine的,一个goroutine通过chanel向另一个goroutine发送消息,对应的goroutine通过channel来接受消息。
如何定义channel
var <变量名称> chan <数据类型>
var intChan chan int
var strChan chan string
var strChan chan *string
var objChan chan struct{}
channel是引用类型。
需要使用make方法来实例化
make(chan int) # 不带缓存(buffer)的channel
make(chan int,3) # 带缓存(buffer)的channel
make(chan *string)
make(chan *map[string]struct)
示例
func TestDefChannel(t *testing.T){
var intCh chan int
fmt.Println("intChan",intCh) // <nil>
intCh = make(chan int,1)
fmt.Println("intCh",intCh) // 0xc****
}
Channel特性
1、Channel本质是一个队列,先进先出
2、Channel本身是线程安全的,多个goroutine去操作它,是安全的
3、Channel是数据类型敏感的
示例
func TestDefChannel(t *testing.T){
intCh := make(chan int,1)
fmt.Println("intCh",intCh)
intCh <- 3
out := <- intCh
fmt.Println(out)
}
Channel的操作
添加数据
intChan <- 8
取出数据
out <- intChan
func main() {
// 创建一个不带buffer缓存的channel
// 该channel用于传递int类型的数据
IntChan := make(chan int)
workerCount := 10
for i := 0; i < workerCount; i++ {
go func(i int) {
IntChan <- i
}(i)
}
for j := 0; j < workerCount; j++ {
go func(j int) {
// 从IntChan中接收数据
num := <-IntChan
// 打印接收到的数据
fmt.Printf("Received: %d\n", num)
}(j)
}
// 等待所有goroutine完成
time.Sleep(1 * time.Second)
}
Received: 0
Received: 4
Received: 1
Received: 2
Received: 3
Received: 9
Received: 5
Received: 6
Received: 7
Received: 8
对于没有缓冲区的channel而言,如果没有channel没有出,它是无法写入数据的。
遍历
Channel 只能通过for... range遍历
如果channel没有关闭,也没有数据进入的话,那么就会报错,死锁。
关闭的Channel无法再装入数据,可以继续取数据,直到channel为空
intCh := make(chan int ,10)
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
for i :=range intCh{
fmt.Println(i)
}
1
1
1
1
1
1
fatal error: all goroutines are asleep - deadlock!
一定要记得关闭不使用的channel
intCh := make(chan int ,10)
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
close(intCh)
for i :=range intCh{
fmt.Println(i)
}
或者
func main() {
intCh := make(chan int, 10)
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
intCh <- 1
close(intCh)
for {
if data, ok := <-intCh; ok {
fmt.Println(data)
} else {
fmt.Println("Channel has been closed")
break
}
}
}