美文网首页
Select简明教程

Select简明教程

作者: 危地马拉的大坑 | 来源:发表于2020-12-20 22:50 被阅读0次

select关键字到底有什么作用?下面先来一个简单例子说明:

func main(){
    fmt.Println(time.Now().Format("15:04:05") + " Go Select Statement Tutorial")

    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        time.Sleep(1 * time.Second)
        ch1 <- "video data"
    }()

    go func() {
        time.Sleep(2 * time.Second)
        ch2 <- "audio data"
    }()

    fmt.Println(time.Now().Format("15:04:05"), "Started goroutine!!")
    for i := 0; i < 2; i++ {
        select {
        case msg1 := <- ch1:
            fmt.Println(time.Now().Format("15:04:05"), "Received: ", msg1)
        case msg2 := <- ch2:
            fmt.Println(time.Now().Format("15:04:05"), "Received: ", msg2)
        }
    }
}

创建两个Channel和两个子协程分别向一个Channel发送信息,执行看看打印日志:

~ » go run main.go
12:33:29 Go Select Statement Tutorial
12:33:29 Started goroutine!!
12:33:30 Received:  video data
12:33:31 Received:  audio data

看日志可以发现主协程在启动完两个子协程,到select关键字的时候发生阻塞了!等待第一个子协程睡眠1s后发送消息到Channel,主协程才继续执行打印日志,再过1s第二个子协程发送消息,主协程继续打印。

那么我们可以得出简单的结论,select关键字有点像阻塞版的switch,不过它只针对Channel,等待Channel有信息返回时可以为不同的Channel触发相应的行为。

我们看下官方有关Select关键字的描述:

A "select" statement chooses which of a set of possible send or receive operations will proceed. It looks similar to a "switch" statement but with the cases all referring to communication operations.
一个select语句用来选择哪个case中的发送或接收操作可以被立即执行。它类似于switch语句,但是它的case涉及到channel有关的I/O操作。

或者换一种说法,select就是用来监听和channel有关的IO操作,当 IO 操作发生时,触发相应的动作。

修改上面的基础使用方法我们会看到什么效果呢?

修改一

修改for循环的次数:

  • 修改为1时,for循环次数比子协程次数少,那么在主协程结束前只有一个子协程执行完成,主协程不会等待剩余的子协程。即,一个select关键字只会等待一个Channl

    ~ » go run main.go
    12:49:51 Go Select Statement Tutorial
    12:49:51 Started goroutine!!
    12:49:52 Received:  video data
    
  • 修改为3时,for循环次数比子协程次数多,那么等待完两个Channel的消息后,会引入死锁状态。

    ~ » go run main.go
    12:52:08 Go Select Statement Tutorial
    12:52:08 Started goroutine!!
    12:52:09 Received:  video data
    12:52:09 Finished ch1
    12:52:10 Finished ch2
    12:52:10 Received:  audio data
    fatal error: all goroutines are asleep - deadlock!
    
    goroutine 1 [select]:
    main.main()
            ~/main.go:28 +0x32c
    exit status 2
    
    

修改二

在select所包含的代码块里添加default关键字,看看什么效果:

for i := 0; i < 2; i++ {
        select {
        case msg1 := <- ch1:
            fmt.Println(time.Now().Format("15:04:05"), "Received: ", msg1)
        case msg2 := <- ch2:
            fmt.Println(time.Now().Format("15:04:05"), "Received: ", msg2)
        default:
            fmt.Println(time.Now().Format("15:04:05"), "execute default")
        }
    }

打印日志如下:

~ » go run main.go
12:55:05 Go Select Statement Tutorial
12:55:05 Started goroutine!!
12:55:05 execute default
12:55:05 execute default

发现select关键字再也不阻塞等待Channel返回的,继续执行知道主协程结束。

修改三

在case里加入break关键字,会马上返回,不再继续执行。

for i := 0; i < 2; i++ {
        select {
        case msg1 := <- ch1:
            fmt.Println(time.Now().Format("15:04:05"), "Received: ", msg1)
            break
            fmt.Println(time.Now().Format("15:04:05"), "print2")
        case msg2 := <- ch2:
            fmt.Println(time.Now().Format("15:04:05"), "Received: ", msg2)
            fmt.Println(time.Now().Format("15:04:05"), "print2")
        }
    }

执行日志如下:

~ » go run main.go
13:01:45 Go Select Statement Tutorial
13:01:45 Started goroutine!!
13:01:46 Finished ch1
13:01:46 Received:  video data
13:01:47 Finished ch2
13:01:47 Received:  audio data
13:01:47 print3

可以看到case msg1 := <- ch1:情况发生时,执行完第一句打印,然后遇上break关键字马上停止了下面语句的执行。

午安~

相关文章

  • Select简明教程

    select关键字到底有什么作用?下面先来一个简单例子说明: 创建两个Channel和两个子协程分别向一个Chan...

  • OPENGL ES 教程

    Android OpenGL ES 简明开发教程一:概述Android OpenGL ES 简明开发教程二:构造O...

  • webpack 几个很棒的教程

    初学webpack,网上找到了几个简明易懂的入门教程十分感谢教程的作者! WebPack 简明学习教程 Webpa...

  • Linux 常用命令总结

    linux 命令速查手册linux 常用操作命令 sed 简明教程 awk 简明教程 常用命令 ls ...

  • Socket使用简明教程- AsyncSocket

    Socket使用简明教程- AsyncSocket

  • 数据库学习线路图

    SQL 语法教程 SQL 教程SQL 简介SQL 语法SQL Select选择SQL SELECT DISTINC...

  • Markdown语法

    经常忘记,写个备忘录。简明教程1简书教程

  • SQL 语句教程

    SQL 语句教程 SQL语句教程(01) SELECT.................................

  • SQL 语句教程3

    SQL 语句教程SQL语句教程(01) SELECT..................................

  • pycaffe使用

    pycaffe简明文档Caffe for Python 官方教程(翻译) pycaffe使用教程 caffe添加C...

网友评论

      本文标题:Select简明教程

      本文链接:https://www.haomeiwen.com/subject/qujlnktx.html