golang|golang select

使用场景

select主要用来监控多个channel,channel的数据读取,写入,关闭等事件,采用的是轮训算法

监控事件
channel读取事件 channel的写入事件 channel关闭事件 其他default

读取事件
func addNumberToChan(chanName chan int) { for { chanName <- 1 time.Sleep(1 * time.Second) } } // select 监控channel的push事件 func testReadChannel(){ var chan1 = make(chan int, 10) var chan2 = make(chan int, 10) go addNumberToChan(chan1) go addNumberToChan(chan2) for { select { case e := <- chan1 : fmt.Printf("Get element from chan1: %d\n", e) case e := <- chan2 : fmt.Printf("Get element from chan2: %d\n", e) default: fmt.Printf("No element in chan1 and chan2.\n") time.Sleep(1 * time.Second) } } }

写入事件
func testAddChannel(){ var chan1 = make(chan int, 10) var chan2 = make(chan int, 10)chan1 <- 1 chan2 <- 0 //go addNumberToChan(chan1) //go addNumberToChan(chan2)for { select { case chan1 <- 1 : fmt.Printf("Get element from chan1: 1") case chan2 <- 0 : fmt.Printf("Get element from chan2: 0") default: fmt.Printf("No element in chan1 and chan2.\n") time.Sleep(1 * time.Second) } }

}
PS:注意select语句如果做监听使用的话,尽量嵌套在for循环中,因为单独的select是阻塞的,并且是又返回值的,eg:
func server1(ch chan string) { time.Sleep(1 * time.Second) ch <- "from server1" } func server2(ch chan string) { time.Sleep(1 * time.Second) ch <- "from server2"} func main() { output1 := make(chan string,1) output2 := make(chan string,1) go server1(output1) go server2(output2) select { case s1 := <-output1: fmt.Println(s1) case s2 := <-output2: fmt.Println(s2) }

【golang|golang select】这个程序的结果要么是“from server1”或者“from server2”,因为select读取到一个数据后就返回了

    推荐阅读