1、channel是goroutine之间的交互,不可以在单个goroutine里面
2、发到channel里的数据当时还没有goroutine收就会deadLock(发数据必须有人取)
func work(){ //var c chan int //声明 c := make(chan int) //创建chan //a :=<- c这样不行,因为channel是goroutine之间的交互,不可以在单个goroutine里面 go func(){ for{ a := <-c fmt.Println(a) } }() c <- 1 //此句话如果放在go func()上面,会deadLock,发到channel里的数据当时还没有goroutine收就会deadLock } func main(){ work() time.Sleep(time.Minute) }
3、channel作为参数
func work(id int,c chan int) { for{ a := <-c fmt.Printf("work %d received %d\n",id,a) } } func chanMake(){ var channels [9]chan int for i:=0;i<9;i++ { channels[i] = make(chan int) go work(i,channels[i]) } for i:=0;i<9;i++ { channels[i] <- i } } func main(){ chanMake() time.Sleep(time.Minute) }
4、channel作为返回值
func work(id int) chan int {//chan作为返回值 c := make(chan int) go func(){ for{ fmt.Printf("work %d received %d\n",id,<-c) } }() return c } func chanMake(){ var channels [9]chan int for i:=0;i<9;i++ { channels[i] = work(i) } for i:=0;i<9;i++ { channels[i] <- i } } func main(){ chanMake() time.Sleep(time.Millisecond) }
4、单向channel
func work(id int) chan<- int { //外面只能发数据 c := make(chan int) go func(){ for{ fmt.Printf("work %d received %d\n",id,<-c) //里面只能收数据 } }() return c } func chanMake(){ var channels [9]chan<- int //单向chan for i:=0;i<9;i++ { channels[i] = work(i) } for i:=0;i<9;i++ { channels[i] <- i } }
5、缓冲channel ------------- 可以将这些值发送到通道中,而没有相应的并发接收。
func work(id int,c chan int) { for{ a := <-c fmt.Printf("work %d received %d\n",id,a) } } func bufferedChannel(){ c := make(chan int ,2)//缓冲通道接受有限数量的值 go work(0,c) c <- 1 c <- 2 c <- 3 c <- 4 time.Sleep(time.Millisecond) } func main(){ bufferedChannel() time.Sleep(time.Millisecond) }
6、关闭channel
close后仍然可以从中读取以发送的数据,读取完数据后,将读取到零值,可以多次读取。若没有close,则只能读已经发送进来的数据
func work0(id int,c chan int) { /* for{ a,ok := <-c if !ok { break } fmt.Printf("work %d received %d\n",id,a) }*/ for a := range c{ //注释代码和此段代码效果相同,range,当通道里没有数据就不读了 fmt.Printf("work %d received %d\n",id,a) } } func channelClose(){ c := make(chan int) go work0(0,c) c <- 1 c <- 2 c <- 3 c <- 4 close(c) //close后仍然可以从中读取以发送的数据,读取完数据后,将读取到零值,可以多次读取 time.Sleep(time.Millisecond) } func main(){ channelClose() time.Sleep(time.Millisecond) }