管道channel的关闭和遍历以及死锁的产生
内建函数close关闭信道,该通道必须为双向的或只发送的。
它应当只由发送者执行,而不应由接收者执行,其效果是在最后发送的值被接收后停止该通道。
在最后的值从已关闭的信道中被接收后,任何对其的接收操作都会无阻塞的成功。对于已关闭的信道,
语句∶
x , ok := <-c
还会将ok置为false
channel支持for-range的方式进行遍历,请注意两个细节
1.在遍历的时候,如果channel没有关闭,则会出现deadlock的错误。
2.在遍历的时候,如果channel已经关闭,则会正常遍历数据,遍历完后会退出遍历。
package main
import(
"fmt"
)
// 内建函数close关闭信道,该通道必须为双向的或只发送的。
// 它应当只由发送者执行,而不应由接收者执行,其效果是在最后发送的值被接收后停止该通道。
// 在最后的值从已关闭的信道中被接收后,任何对其的接收操作都会无阻塞的成功。对于已关闭的信道,
// 语句∶
// x , ok := <-c
// 还会将ok置为false
//channel支持for-range的方式进行遍历,请注意两个细节
//1.在遍历的时候,如果channel没有关闭,则会出现deadlock的错误。
//2.在遍历的时候,如果channel已经关闭,则会正常遍历数据,遍历完后会退出遍历。
//遍历管道案例
func main(){
intChan2 :=make(chan int,100)
//这个是因为:=操作符导致的,:=不能用于声明全局变量!只能在函数内部使用。
//:=只用来声明临时变量, 初始化全局变量需使用var关键字,正确操作如下:
for i := 0;i < 100;i++ {
intChan2 <- i * 2
}
//遍历管道的时候,不能使用普通的for循环结构
//比如使用for i:= 0;i < len(intChan2);i++{ } 会失败
//前提是会把管道关闭,当取完的时候会及时的停止。
//在遍历的时候,如果channel没有关闭,则会出现deadlock的错误。
close(intChan2)
for v := range intChan2{
fmt.Println("v=",v)
}
}
//遍历管道的时候,不能使用普通的for循环结构
//比如使用for i:= 0;i < len(intChan2);i++{ } 会失败
//前提是会把管道关闭,当取完的时候会及时的停止。
//在遍历的时候,如果channel没有关闭,则会出现deadlock的错误。
close(intChan2)
for v := range intChan2{
fmt.Println("v=",v)
}