go基础入门之 select(多路复用)

2019-07-25 16:27:29 浏览数 (1)

之前我们停车模拟采用的switch来随机生成0 1 模拟进行enter leave,现在我们采用select进行分支切换。那么什么是select呢?select会随机的执行一个channel或者default,从而能够使每个channel能够有均等的执行概率

代码语言:javascript复制

type Bus int

var station = 50

func leave() <-chan Bus {
  defer time.Sleep(time.Microsecond*500)

  bus := make(chan Bus,1)
  defer close(bus)
  if station > 0 {
    bus <- -1
    return bus
  } else {
    bus <- 0
  }
  return bus
}
func enter() chan Bus {
  en := make(chan Bus,1)
  defer close(en)
  if station == 50{
    en <- 0
  }else {

    en <- 1
  }
  defer time.Sleep(time.Microsecond*500)
  return en
}
func main() {

  for station>0 {
    select {
    case en:= <-enter():
      if en == 0 {
        fmt.Println("can not enter")
         continue
      }
      station  = int(en)
      fmt.Println("enter station:",station)

    case value := <-leave():
      if value==0 {
        fmt.Println("is empty")
        continue
      }
      station  = int(value)
      fmt.Println("leave station:",station)

    }
  }

}

对于一个station车进出事随机的,正好符合我们的select执行规律。对于上文怎么我们采用for来进行无下限的循环等待。那么对于select怎么样去结束一个执行呢?break是常用的方式。然而break只是结束了内部的select并不能控制完部的for。因此,怎么正确的退出一个select循环呢?我们看下例解决

代码语言:javascript复制
a := make(chan bool)
loop:
  for {
    select {
    case <-a:
      break loop

    }
  }

在for的外层设置一个loop的循环标志,当需要完全退出的时候break loop即可完全退出select和for的循环

0 人点赞