旺仔小糖

关于for select case a year ago

go
并发
1141个字符
共有100人围观

博客大纲

for selcet case是很高效的, 比如case A正在执行,如果此时case B有值,那么case B也会执行,它就像银行的多窗口柜台 哪个窗口有人排队哪个case就去接待

来看个例子:

package main

import (
	"time"
)

func main() {
	ch_sheep := make(chan string)
	ch_cow := make(chan string)

	go func() {
		for {
			ch_sheep <- genSheep()
		}
	}()

	go func() {
		for {
			ch_cow <- genCow()
		}
	}()

	for {
		select {
		case s := <-ch_sheep:
			println(s)
		case c := <-ch_cow:
			println(c)
		case <-time.After(time.Second * 10):
			println("Timeout")
		}
	}
}

func genSheep() string {
	time.Sleep(time.Second * 5)
	return "🐑"
}

func genCow() string {
	time.Sleep(time.Second)
	return "🐮"
}

羊5秒输出一次,牛1秒输出一次

  • 如果同一时刻只能执行一个case,那么羊输入的前5s不会有任何输出,因为case被genSheep()占用了,结果是牛羊随机
  • 如果同一时刻可以执行多个case,那么牛输入5次,羊输入一次

运行

可以看到中间是没有停顿的

总结

  • 各case之间互不干扰,只与对应的channel有关,如果channel没有buffer就起到阻塞同步的作用
  • for select case常用于处理后台任务;如果有多个不相干的任务 可以用多个function来处理
func task1() {
	for {
		select {
		//todo
		case <-time.After(time.Second * 10):
			println("Timeout")
			return
		}
	}
}

func task2() {
	for {
		select {
		//todo
		case <-time.After(time.Second * 10):
			println("Timeout")
			return
		}
	}
}