packagemainimport("fmt""time")funcmain(){varchchanintgofunc(){ch<-1fmt.Println("goroutine finish")}()time.Sleep(10*time.Second)}// main goroutine 会等待10s,不会打印goroutine finish,说明一直阻塞
缓冲通道,已满,进行发送操作,发送操作阻塞
packagemainimport("fmt""time")funcmain(){varch=make(chanint,3)ch<-1ch<-2ch<-3fmt.Println("channel is fill")gofunc(){ch<-4fmt.Println("fill channel can receive a number?")}()time.Sleep(5*time.Second)}
packagemainimport"fmt"funcmain(){varch=make(chanint,2)gofunc(){fori:=0;i<10;i++{fmt.Println("sender channel a val: ",i)ch<-i}fmt.Println("sender finished, will close the channel")close(ch)}()for{elem,ok:=<-chif!ok{fmt.Println("channel has already closed.")break}else{fmt.Println("receive a val from channel, ",elem)}}fmt.Println("End.")}
// 给定几个通道,哪个通道不为空,便执行相应语句
// 准备好几个通道。
intChannels:=[3]chanint{make(chanint,1),make(chanint,1),make(chanint,1),}// 随机选择一个通道,并向它发送元素值。
index:=rand.Intn(3)fmt.Printf("The index: %d\n",index)intChannels[index]<-index// 哪一个通道中有可取的元素值,哪个对应的分支就会被执行。
select{case<-intChannels[0]:fmt.Println("The first candidate case is selected.")case<-intChannels[1]:fmt.Println("The second candidate case is selected.")caseelem:=<-intChannels[2]:fmt.Printf("The third candidate case is selected, the element is %d.\n",elem)default:fmt.Println("No candidate case is selected!")}
funcexample2(){intChan:=make(chanint,1)// 一秒后关闭通道。
time.AfterFunc(time.Second,func(){close(intChan)})select{case_,ok:=<-intChan:if!ok{fmt.Println("The candidate case is closed.")break}fmt.Println("The candidate case is selected.")}}// result
Thecandidatecaseisclosed.
程序分析,代码运行到select的唯一case分支时,因为此时intChan为空,无法进行接收,所以阻塞,1s之后,通道关闭,二元接收值中的ok为false,所以执行答应The candidate case is closed.
再次看一个示例,到底哪个case被执行,或者default被执行
packagemainimport"fmt"varchannels=[3]chanint{nil,make(chanint),nil,}varnumbers=[]int{0,1,2}funcmain(){select{casegetChan(0)<-getNumber(0):fmt.Println("The first candidate case is selected.")casegetChan(1)<-getNumber(1):fmt.Println("The second candidate case is selected.")casegetChan(2)<-getNumber(2):fmt.Println("The third candidate case is selected")default:fmt.Println("No candidate case is selected!")}}funcgetNumber(iint)int{fmt.Printf("numbers[%d]\n",i)returnnumbers[i]}funcgetChan(iint)chanint{fmt.Printf("channels[%d]\n",i)returnchannels[i]}// result
Nocandidatecaseisselected!
packagemainimport"fmt"varchannels=[3]chanint{nil,make(chanint),nil,}varnumbers=[]int{0,1,2}funcmain(){gofunc(){for{<-getChan(1)}}()select{casegetChan(0)<-getNumber(0):fmt.Println("The first candidate case is selected.")casegetChan(1)<-getNumber(1):fmt.Println("The second candidate case is selected.")casegetChan(2)<-getNumber(2):fmt.Println("The third candidate case is selected")default:fmt.Println("No candidate case is selected!")}fmt.Println("finish")}funcgetNumber(iint)int{fmt.Printf("numbers[%d]\n",i)returnnumbers[i]}funcgetChan(iint)chanint{fmt.Printf("channels[%d]\n",i)returnchannels[i]}