- 启动两个做为生产者的go-routing,
- 分别将数据生产的数据写入两个带缓冲的通道cha1,ch2
- 分别模拟在Main go-routing和 sub go-routing中通过for-select循环读取两个通道的值并打印
- 通过3种方式优雅的退出main go-routing
exit for-select in go-routing
https://play.golang.org/p/Ar4389-87QE
package main
import (
// "time"
"fmt"
)
func produce(id int, ch chan string, quitSub chan int){
for i:=0;i< 10;i++{
ch <- fmt.Sprintf("msg:%d:%d",id,i)
}
quitSub <- id
}
func main() {
c1 := make(chan string, 1) //定义两个有缓冲的通道,容量为1
c2 := make(chan string, 1)
quitForSelect := make(chan int, 2) //用于通知退出for select循环
quitTag := []int{} //用于读取和存储quitForSlect通道的两个值,保证两个product都写入完毕
quitMain := make(chan bool) //阻塞main gorouting,等待for select 处理完成
go produce(1, c1, quitForSelect)
go produce(2, c2, quitForSelect)
go func(){
for { //使用select来等待这两个通道的值,然后输出
select {
case msg1 := <- c1:
fmt.Println(msg1)
case msg2 := <- c2:
fmt.Println(msg2)
case q := <- quitForSelect:
fmt.Println("got quit tag for Gorouting id:", q)
quitTag = append(quitTag,q)
if len(quitTag) == 2{
fmt.Println("end to quit Main ")
quitMain <- true
}
}
}
}()
<-quitMain
fmt.Println("exit from main")
}
exit for-select by "break" in Main go-routing
https://play.golang.org/p/vEUvAslRqVw
package main
import (
"fmt"
)
func produce(id int, ch chan string, quitSub chan int) {
for i := 0; i < 10; i++ {
ch <- fmt.Sprintf("msg:%d:%d", id, i)
}
quitSub <- id
}
func main() {
c1 := make(chan string, 1) //定义两个有缓冲的通道,容量为1
c2 := make(chan string, 1)
quitForSelect := make(chan int, 2) //用于通知退出for select循环
quitTag := []int{} //用于读取和存储quitForSlect通道的两个值,保证两个product都写入完毕
go produce(1, c1, quitForSelect)
go produce(2, c2, quitForSelect)
ForEnd:
for { //使用select来等待这两个通道的值,然后输出
select {
case msg1 := <-c1:
fmt.Println(msg1)
case msg2 := <-c2:
fmt.Println(msg2)
case q := <-quitForSelect:
fmt.Println("got quit tag for Gorouting id:", q)
quitTag = append(quitTag, q)
if len(quitTag) == 2 {
fmt.Println("end to quit Main ")
break ForEnd
}
}
}
fmt.Println("exit from main")
}
exit for-select by "goto" in Main go-routing
https://play.golang.org/p/GKD_NYpoMdT
package main
import (
"fmt"
)
func produce(id int, ch chan string, quitSub chan int) {
for i := 0; i < 10; i++ {
ch <- fmt.Sprintf("msg:%d:%d", id, i)
}
quitSub <- id
}
func main() {
c1 := make(chan string, 1) //定义两个有缓冲的通道,容量为1
c2 := make(chan string, 1)
quitForSelect := make(chan int, 2) //用于通知退出for select循环
quitTag := []int{} //用于读取和存储quitForSlect通道的两个值,保证两个product都写入完毕
go produce(1, c1, quitForSelect)
go produce(2, c2, quitForSelect)
for { //使用select来等待这两个通道的值,然后输出
select {
case msg1 := <-c1:
fmt.Println(msg1)
case msg2 := <-c2:
fmt.Println(msg2)
case q := <-quitForSelect:
fmt.Println("got quit tag for Gorouting id:", q)
quitTag = append(quitTag, q)
if len(quitTag) == 2 {
fmt.Println("end to quit Main ")
goto ForEnd
}
}
}
ForEnd:
fmt.Println("go to here from for-select")
fmt.Println("exit from main")
}