golang ---------- channel 通道(一 基本操作)

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)
}

猜你喜欢

转载自blog.csdn.net/qq_36183935/article/details/80039448