Select {.en}

通道选择器 {.zh}

::: {.en} Go’s select lets you wait on multiple channel operations. Combining goroutines and channels with select is a powerful feature of Go. :::

::: {.zh}

Go 的通道选择器让你可以同时等待多个通道操作。Go 协程和通道以及选择器的结合是 Go 的一个强大特性。

:::

  1. package main
  2. import "time"
  3. import "fmt"
  4. func main() {

::: {.en} For our example we’ll select across two channels. :::

::: {.zh}

对于我们的示例,我们将在两个通道中选择。

:::

  1. c1 := make(chan string)
  2. c2 := make(chan string)

::: {.en} Each channel will receive a value after some amount of time, to simulate e.g. blocking RPC operations executing in concurrent goroutines. :::

::: {.zh}

各个通道将在若干时间后接收一个值,这个用来模拟例如 并行的 Go 协程中阻塞的 RPC 操作

:::

  1. go func() {
  2. time.Sleep(1 * time.Second)
  3. c1 <- "one"
  4. }()
  5. go func() {
  6. time.Sleep(2 * time.Second)
  7. c2 <- "two"
  8. }()

::: {.en} We’ll use select to await both of these values simultaneously, printing each one as it arrives. :::

::: {.zh}

我们使用 select 关键字来同时等待这两个值,并打 印各自接收到的值。

:::

  1. for i := 0; i < 2; i++ {
  2. select {
  3. case msg1 := <-c1:
  4. fmt.Println("received", msg1)
  5. case msg2 := <-c2:
  6. fmt.Println("received", msg2)
  7. }
  8. }
  9. }

::: {.en} We receive the values "one" and then "two" as expected. :::

::: {.zh}

我们首先接收到值 “one”,然后就是预料中的 “two” 了。

:::

  1. $ time go run select.go
  2. received one
  3. received two

::: {.en} Note that the total execution time is only ~2 seconds since both the 1 and 2 second Sleeps execute concurrently. :::

::: {.zh}

注意从第一次和第二次 Sleeps 并发执行,总共仅运行了 两秒左右。

:::

  1. real 0m2.245s