美文网首页
select详解

select详解

作者: 只争朝夕々 | 来源:发表于2020-07-05 11:46 被阅读0次

语法具体定义参考官方定义

https://golang.org/ref/spec#Select_statements

select语句执行分以下一个步骤执行

  • 所有channel表达式都会被求值、所有被发送的表达式都会被求值。求值顺序:自上而下、从左到右。
  • 如果有一个或多个通信操作可以完成,则Go运行时系统会伪随机的选择一个执行。否则,如果有default分支,则执行default分支语句,如果连default都没有,则select语句会一直阻塞,直到至少有一个通信操作可以进行。

案例分析

所有channel表达式都会被求值、所有被发送的表达式都会被求值。求值顺序:自上而下、从左到右

func main() {
    var ch1 chan int
    var ch2 chan int
    var chs = []chan int{ch1, ch2}
    var numbers = []int{1, 2, 3, 4, 5}

    getNumber := func(i int) int {
        fmt.Printf("numbers[%d]\n", i)
        return numbers[i]
    }

    getChan := func(i int) chan int {
        fmt.Printf("chs[%d]\n", i)
        return chs[i]
    }

    select {
    case getChan(0) <- getNumber(2):
        fmt.Println("1th case is selected.")
    case getChan(1) <- getNumber(3):
        fmt.Println("2th case is selected.")
    default:
        fmt.Println("default case")
    }
}

输出:

chs[0]
numbers[2]
chs[1]
numbers[3]
default case

Process finished with exit code 0

如果有一个或多个通信操作可以完成,则Go运行时系统会伪随机的选择一个执行。否则,如果有default分支,则执行default分支语句,如果连default都没有,则select语句会一直阻塞,直到至少有一个通信操作可以进行

  • 所有case语句都被阻塞时,如果有default语句,执行default语句
func main() {
    start := time.Now()
    ch1 := make(chan int)
    ch2 := make(chan int)

        go func() {
        time.Sleep(2 * time.Second)
        ch1 <- 3
    }()

    go func() {
        time.Sleep(3 * time.Second)
        ch2 <- 5
    }()

    fmt.Println("blocking on read...")

    select {
    case <-ch1:
        fmt.Printf("ch1 case...")
    case <-ch2:
        fmt.Printf("ch2 case...")
    default:
        fmt.Printf("default case...")
    }
}

输出:

blocking on read...
default case...
Process finished with exit code 0
  • 所有case语句都被阻塞时,当没有default语句时,select阻塞等待
func main() {
    start := time.Now()
        ch1 := make(chan int)
    ch2 := make(chan int)

    go func() {
        time.Sleep(2 * time.Second)
        ch1 <- 3
    }()

    go func() {
        time.Sleep(3 * time.Second)
        ch2 <- 5
    }()

    fmt.Println("blocking on read...")

    select {
    case <-ch1:
        fmt.Printf("ch1 case...")
    case <-ch2:
        fmt.Printf("ch2 case...")
    }
}

输出:

blocking on read...
ch1 case...
Process finished with exit code 0
  • 当多个case语句都可以被执行时,伪随机的选择一个执行
func main() {
    start := time.Now()
    ch1 := make(chan int)
    ch2 := make(chan int)

    go func() {
        time.Sleep(1 * time.Second)
        ch1 <- 3
    }()

    go func() {
        time.Sleep(1 * time.Second)
        ch2 <- 5
    }()

    fmt.Println("blocking on read...")

    select {
    case <-ch1:
        fmt.Printf("ch1 case...")
    case <-ch2:
        fmt.Printf("ch2 case...")
    }
}

输出:

blocking on read...
ch1 case...
Process finished with exit code 0
blocking on read...
ch2 case...
Process finished with exit code 0

相关文章

  • Select_poll_epoll详解

    Select_poll_epoll详解 Select_poll_epoll详解参考链接epoll函数closeep...

  • JAVA使用Jsoup的select语法进行元素查找

    select详解 Document 继承自 Element 类。select方法将返回一个Elements集合。 ...

  • Jsoup的select语法

    select详解Document 继承自 Element 类。select方法将返回一个Elements集合。 1...

  • select详解

    语法具体定义参考官方定义 https://golang.org/ref/spec#Select_statement...

  • 小知识点(二)

    select、poll、epoll区别:详解三者区别 select,poll,epoll都是IO多路复用的机制。I...

  • IO多路复用之select、poll、epoll详解lw

    IO多路复用之select、poll、epoll详解 目前支持I/O多路复用的系统调用有select,pselec...

  • MySQL Explain

    结果详解 共有10列:id,select_type,table,type,partitions,possible_...

  • select---详解

    前言 传统的服务器框架都是阻塞I/O类型的,为了提高并发性将迭代型(while)改为多进程,但是多进程开销较大,然...

  • select()函数详解

    在Linux中,我们可以使用select函数实现I/O端口的复用,传递给select函数的参数会告诉内核: 我们关...

  • Go Select 详解

    导读 select是一种go可以处理多个通道之间的机制,看起来和switch语句很相似,但是select其实和IO...

网友评论

      本文标题:select详解

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