golang-chan和select的使用

select是Go中的一个控制结构,类似于switch语句,用于处理异步IO操作。select会监听case语句中channel的读写操作,当case中channel读写操作为非阻塞状态(即能读写)时,将会触发相应的动作。

package main

import (
	"fmt"
	"time"
)

var in1=make(chan int,10)
var in2=make(chan int,1)

func f11() {
	time.Sleep(time.Second * 3)
EVENT_LOOP:
	for {
		select {
		case job := <-in1:
			fmt.Println(job)
		case aaaa:=<-in2:
			fmt.Println(aaaa)
			break EVENT_LOOP
		}
	}
}
func f22(){
	for i:=0;i<10;i++{
		in1<-i
	}
}
func f33(){
	in2<-111
}

func main(){
	go f22()
	go f33()
	go f11()
	time.Sleep(time.Second * 10)
}

1、如果有多个case都可以运行,select会随机公平地选出一个执行,其他不会执行。从执行结果中可以看出,当通道in1和in2都有数据时(in2是用于结束for循环),多次执行结果不同。

golang-chan和select的使用_第1张图片 golang-chan和select的使用_第2张图片

当chan通道为空时,<-in(chan)会使程序陷入阻塞

package main

import (
	"fmt"
	"time"
)
var in3=make(chan int,1)
func ff(){

	select{
	case a:=<-in3:
		fmt.Println("aaaa",a)
	}
}

func main(){
	go ff()
	//in3<-10
	time.Sleep(time.Second*5)

	fmt.Println("FINAL")
}

当注释掉代码“in3<-10”时,通道in3中一直无数据,阻塞

golang-chan和select的使用_第3张图片 golang-chan和select的使用_第4张图片
//in3<-10 主程序退出,协程阻塞 in3<-10

3、close(chan) 使所有通道的接受者都进入非阻塞

package main

import (
	"fmt"
	"time"
)


var in=make(chan int,1)

func f1(){
	WWW:
	for {
		select {
		case <-in:
			fmt.Println("aa")
			break WWW
		}
	}
}
func f2(){

	WWW:
	for {
		select {
		case <-in:
			fmt.Println("bb")
			break WWW
		}
	}
}

func main(){

	go f1()
	go f2()
	time.Sleep(time.Second*2)

	//close(in)
	//in<-10
	time.Sleep(time.Second * 10)

}
当close(in)和in<-10都被注释掉,两个协程阻塞,主函数退出 当只注释掉close(in)只会阻塞其中一个协程
golang-chan和select的使用_第5张图片 golang-chan和select的使用_第6张图片
当close(in)取消注释,两个协程都会进入非阻塞
golang-chan和select的使用_第7张图片

你可能感兴趣的:(go语言学习)