当前位置: 代码迷 >> 综合 >> golang-chan和select的使用
  详细解决方案

golang-chan和select的使用

热度:61   发布时间:2023-10-13 09:37:56.0

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

package mainimport ("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的使用 golang-chan和select的使用

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

package mainimport ("fmt""time"
)
var in3=make(chan int,1)
func ff(){select{case a:=<-in3:fmt.Println("aaaa",a)}
}func main(){go ff()//in3<-10time.Sleep(time.Second*5)fmt.Println("FINAL")
}

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

golang-chan和select的使用 golang-chan和select的使用
//in3<-10 主程序退出,协程阻塞 in3<-10

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

package mainimport ("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<-10time.Sleep(time.Second * 10)}
当close(in)和in<-10都被注释掉,两个协程阻塞,主函数退出 当只注释掉close(in)只会阻塞其中一个协程
golang-chan和select的使用 golang-chan和select的使用
当close(in)取消注释,两个协程都会进入非阻塞
golang-chan和select的使用
  相关解决方案