美文网首页
select用法

select用法

作者: Uzero | 来源:发表于2018-03-06 18:23 被阅读0次

golang 的 select 的功能和select, poll, epoll相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。

示例:

ch1 := make (chan int, 1)

ch2 := make (chan int, 1)

...

select {

case <-ch1:

    fmt.Println("ch1 pop one element")

case <-ch2:

    fmt.Println("ch2 pop one element")

}

注意到 select 的代码形式和 switch 非常相似, 不过 select 的 case 里的操作语句只能是【IO 操作】 。

此示例里面 select 会一直等待等到某个 case 语句完成, 也就是等到成功从 ch1 或者 ch2 中读到数据。 则 select 语句结束。

【使用 select 实现 timeout 机制】

如下:

timeout := make (chan bool, 1)

go func() {

    time.Sleep(1e9) // sleep one second   

    timeout <- true

}()

ch := make (chan int)

select {

case <- ch:

case <- timeout:

    fmt.Println("timeout!")

}

当超时时间到的时候,case2 会操作成功。 所以 select 语句则会退出。 而不是一直阻塞在 ch 的读取操作上。 从而实现了对 ch 读取操作的超时设置。

下面这个更有意思一点。

当 select 语句带有 default 的时候:

ch1 := make (chan int, 1)

ch2 := make (chan int, 1)

select {

case <-ch1:

    fmt.Println("ch1 pop one element")

case <-ch2:

    fmt.Println("ch2 pop one element")

default:

    fmt.Println("default")

}

此时因为 ch1 和 ch2 都为空,所以 case1 和 case2 都不会读取成功。 则 select 执行 default 语句。

就是因为这个 default 特性, 我们可以使用 select 语句来检测 chan 是否已经满了。

如下:

ch := make (chan int, 1)

ch <- 1

select {

case ch <- 2:

default:

    fmt.Println("channel is full !")

}

因为 ch 插入 1 的时候已经满了, 当 ch 要插入 2 的时候,发现 ch 已经满了(case1 阻塞住), 则 select 执行 default 语句。 这样就可以实现对 channel 是否已满的检测, 而不是一直等待。

比如我们有一个服务, 当请求进来的时候我们会生成一个 job 扔进 channel, 由其他协程从 channel 中获取 job 去执行。 但是我们希望当 channel 瞒了的时候, 将该 job 抛弃并回复 【服务繁忙,请稍微再试。】 就可以用 select 实现该需求

点击原文

下面代码输出结果是什么?

package main

import (

"fmt"

"runtime"

)

func main() {

    runtime.GOMAXPROCS(1)

    int_chan    :=make(chan int, 1)

    string_chan :=make(chan string, 1)

    int_chan    <-1

    string_chan <-"hello"

    select {

        case value := <-int_chan:

            fmt.Println(value)

        case value := <-string_chan:

            panic(value)

    }

}

考点:select随机性

解答:

select会随机选择一个可用通用做收发操作。 所以代码是有肯触发异常,也有可能不会。 单个chan如果无缓冲时,将会阻塞。但结合 select可以在多个chan间等待执行。有三点原则:

select 中只要有一个case能return,则立刻执行。

当如果同一时间有多个case均能return则伪随机方式抽取任意一个执行。

如果没有一个case能return则可以执行”default”块。

相关文章

  • 温故知新-MYSQL-语法

    查询数据 SELECT SELECT DISTINCT 去重查询 基础用法: SELECT DISTINCT la...

  • Mysql性能分析及explain用法

    explain用法 EXPLAIN [EXTENDED] SELECT select_options 例如: 相关...

  • DQL

    DQL:Data QueryLanguage 数据查询语言 select具体用法 SELECT select_li...

  • select用法

    golang 的 select 的功能和select, poll, epoll相似, 就是监听 IO 操作,当 I...

  • MyBatis XML使用方式

    内容: select用法 insert用法 update用法 delete用法 多个接口参数的用法 动态代理实现原...

  • select 模型

    问题: select是什么?什么是select? select?用于解决什么问题? select的用法? 采用se...

  • sql笔记

    select系列 1、where用法示例: SELECT * FROM Websites WHERE countr...

  • Windows 的 select() 用法

    Windows 的 select() 与 Linux 的 select() 用法类似,但 Windows 的 se...

  • go select + channel 常见用法

    for-select for-select 是一个很常见的用法,select 语句可以从多个可读的 channel...

  • SQL联合查询语言

    SQL 联合查询 ef查询 select where in用法

网友评论

      本文标题:select用法

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