Go语言 Select 详细解读

幸运草 2020年4月16日22:18:36前端框架评论阅读模式

select语句让多个channel操作等待

Go的select语句让程序线程在多个channel的操作上等待,select语句在goroutine 和channel结合的操作中发挥着关键的作用。介绍一个小程序,演示这个select功能。

这个程序模拟接受消息功能,有两个channel接受发送过来的消息。select语句用来接受两个某个消息,for循环表示仅接受3个消息。

package main

import (
    "time"
    "log"
    "strconv"
)

func receiveMsg(){
    c1 := make(chan string)
    c2 := make(chan string)
    t1 := time.Now() // get current time
    go func(){
        //received three message
        for i:=0; i < 3; i++ {
            time.Sleep(time.Millisecond * 150)
            c1 <- "msg 1 with index " + strconv.Itoa(i)
        }
    }()
    go func(){
        for j:=0; j < 3; j++ {
            time.Sleep(time.Millisecond * 200)
            c2 <- "msg 2 with index "+ strconv.Itoa(j)
        }
    }()

    //print two message
    for i:= 0; i < 3; i++ {
        select {
        case msg1 := <- c1:
            log.Println("received msg :", msg1)
        case msg2 := <- c2:
            log.Println("received msg :", msg2)
        }
    }
    elapsed := time.Since(t1)
    log.Println("time elapsed ", elapsed)

}
func main() {
    receiveMsg()
}

输出结果:

2017/02/16 10:55:51 received msg : msg 1 with index 0
2017/02/16 10:55:51 received msg : msg 2 with index 0
2017/02/16 10:55:51 received msg : msg 1 with index 1
2017/02/16 10:55:51 time elapsed  300.03ms

从结果来看,总时间为300多ms,goroutine并发执行对应的休眠时间后,select语句顺利获取对应消息,并打印消息日志。

select随机选择操作

select可以让多个交流操作等待,结合for永久循环,select保证它的case之一能够执行前发生阻塞。 当多个操作都准备好时,select随机选择一个case执行。

下面将介绍一个小程序,演示select的这个功能。

package main

import (
    "log"
    "fmt"
)


func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func exeFibonacci(){
    c := make(chan int)
    quit := make(chan int)

    //produce data
    go func(){
        for i:= 0; i < 10; i++ {
            log.Println("channel data item ", <- c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}

func main() {
    exeFibonacci()
}

输出结果:

2017/02/16 11:35:49 channel data item 0
2017/02/16 11:35:49 channel data item 1
2017/02/16 11:35:49 channel data item 1
2017/02/16 11:35:49 channel data item 2
2017/02/16 11:35:49 channel data item 3
2017/02/16 11:35:49 channel data item 5
2017/02/16 11:35:49 channel data item 8
2017/02/16 11:35:49 channel data item 13
2017/02/16 11:35:49 channel data item 21
2017/02/16 11:35:49 channel data item 34
quit

channel中的每个数字即为fibonacci值(select语句中的x变量值)。

特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
幸运草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" )...

发表评论