首页 > 其他分享 >管道channel

管道channel

时间:2023-01-06 21:45:04浏览次数:35  
标签:ch fmt cap len 管道 Printf channel

管道

go语言中管道底层是一个环形队列(先进先出),写入(send)和 取出(recv)都是从同一个位置按照同一方向顺序执行。
sendx表示最后一次插入元素位置,recvx表示最后一次取出元素的位置
image

管道声明、写入(send)与 取出(recv)

var ch chan int
fmt.Printf("ch is %v\n", ch)  // ch is <nil> 
fmt.Printf("len of ch is %d\n", len(ch))  // len of ch is 0
fmt.Printf("cap of ch is %d\n", cap(ch))  // cap of ch is 0
// 往管道里面写入(send)数据
ch <-1  // fatal error: all goroutines are asleep - deadlock!

为什么会报错呢?在使用管道前一定要初始化管道,给管道一个容量,不然数据无法写入就一直阻塞出现死锁。初始化管道后,管道写满后在写入数据,就无法写入会阻塞,然后就会报错(fatal error: all goroutines are asleep - deadlock! ),同理管道中没有元素了,在从管道中取出元素,也会一直阻塞,然后就报错(fatal error: all goroutines are asleep - deadlock!

var ch chan int
fmt.Printf("ch is %v\n", ch)  // ch is <nil> 
fmt.Printf("len of ch is %d\n", len(ch))  // len of ch is 0
fmt.Printf("cap of ch is %d\n", cap(ch))  // cap of ch is 0
ch = make(chan int, 8)
fmt.Printf("len of ch is %d\n", len(ch))  // len of ch is 0
fmt.Printf("cap of ch is %d\n", cap(ch))  // cap of ch is 8
ch <- 1  //往管道里面写入(send)数据
fmt.Printf("写入1元素后len of ch is %d\n", len(ch))  //写入1元素后len of ch is 1
fmt.Printf("写入1元素后cap of ch is %d\n", cap(ch))  //写入1元素后cap of ch is 8
ch <- 2
fmt.Printf("写入2元素后len of ch is %d\n", len(ch))  //写入2元素后len of ch is 2
fmt.Printf("写入2元素后cap of ch is %d\n", cap(ch))  //写入2元素后cap of ch is 8
v:=<-ch //从管道里面取出(recv)数据
fmt.Println(v) // 1
fmt.Printf("取出一个元素后len of ch is %d\n", len(ch)) //取出一个元素后len of ch is 1
fmt.Printf("取出一个元素后len of ch is %d\n", cap(ch)) //取出一个元素后len of ch is 8

遍历管道

close(ch)  //遍历管道前必须先关闭管道,禁止在写入元素
// 遍历管道里面存在的有的元素
for ele:=range ch {
fmt.Println(ele)
}

标签:ch,fmt,cap,len,管道,Printf,channel
From: https://www.cnblogs.com/lwcbk/p/17031660.html

相关文章