golang 基础(26)select

作者: zidea | 来源:发表于2019-04-02 07:23 被阅读38次
golang_real.jpg

select是Go中的一个控制结构,类似于switch语句,用于处理异步IO操作。select会监听case语句中channel的读写操作,当case中channel读写操作为非阻塞状态(即能读写)时,将会触发相应的动作。

func main(){
    c1 := make(chan string)
    c2 := make(chan string)

    go func(){
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()
    go func(){
        time.Sleep( 2 * time.Second)
        c2 <- "two"
    }()

    for i:= 0; i < 2; i++ {
        select {
            case msg1 := <- c1:
                fmt.Println("received",msg1)
            case msg2 := <- c2:
                fmt.Println("received",msg2)
        
        }
    }
}
th (1).jpg
func main(){
    var c1, c2 chan int
    n1 := <- c1
    n2 := <- c2

    
}

我们创建两个 channel,然后想同时从 c1, c2 来接受数据,然后看 c1, c2 谁发送数据快,谁就先接受谁的数据。

func main(){
    var c1, c2 chan int
    select {
    case n := <- c1:
        fmt.Println("Received from c1:",n)
    case n := <- c2:
        fmt.Println("Received from c2:",n)
    default:
        fmt.Println("No value")
    }


}

我们用 select 来实现上面我们想要效果,不过现在 c1, c2 都是 nil,所以就会走到 default 分支。其实这就是在 channel 里面做了一个非阻塞的处理。在学习我们已经了解到 channel 无论是发数据还是数据都会互相阻塞。
如果去掉 default 就会 deadlock,因为没有人发数据所以就造成了 deadlock


func generator() chan int {
    out := make(chan int)
    go func(){
        i := 0
        for{
            time.Sleep(
                time.Duration(rand.Intn(1500)) * time.Millisecond)
                out <- i
                i++
        }
    }()

    return out;
}

func main(){
    var c1, c2 = generator(),generator()
    select {
    case n := <- c1:
        fmt.Println("Received from c1:",n)
    case n := <- c2:
        fmt.Println("Received from c2:",n)
    
    }


}
func worker(id int, c chan int){
    for n := range c{
        fmt.Printf("Workder %d received %d\n", id, n)
    }
}

func createWorker(id int) chan<- int {
    c := make(chan int)
    go worker(id, c)
    return c
}
func generator() chan int {
    out := make(chan int)
    go func(){
        i := 0
        for{
            fmt.Println("generator")
            time.Sleep(
                time.Duration(rand.Intn(1500)) * time.Millisecond)
                out <- i
                i++
        }
    }()

    return out;
}

func main(){
    var c1, c2 = generator(),generator()
    var worker = createWorker(0)
    n := 0
    hasValue := false
    for {
        var activeWorker chan<- int
        if hasValue {
            activeWorker = worker
        }
        select {
            case n = <- c1:
                hasValue = true
            case n = <- c2:
                hasValue = true
            case activeWorker <- n:
                hasValue = false
        }
    }

}
  • 设置 n = 0,创建一个激活的 activeWorker 为 chan int 类型默认值为 nil 所以会跳过这个。
Golang_cyan.png

相关文章

  • golang 基础(26)select

    select是Go中的一个控制结构,类似于switch语句,用于处理异步IO操作。select会监听case语句中...

  • select I/O多路复用

    select golang的并发模型和linux select类似golang提供了select关键字,实现I/O...

  • Go语言常用代码笔记(持续更新)

    ?循环读取Channel内容 ?golang 的 select 的功能和 select, poll, epoll ...

  • golang select

    使用场景 监控事件 读取事件 写入事件 } PS:注意select语句如果做监听使用的话,尽量嵌套在for循环中,...

  • Go select

    通过select语句可以监听channel上的数据流动 Golang的select语句类似于UNIX的select...

  • select用法

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

  • golang select总结

    官方文档及理解 每个case都必须是一个通信 所有channel表达式都会被求值 所有被发送的表达式都会被求值 如...

  • golang select 小结

    select 介绍 从不同并发执行的协程中,获取数据可以用select来完成。select监听的多个通道,也可以用...

  • Golang select 语句

    select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作...

  • 温故知新-MYSQL-语法

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

网友评论

    本文标题:golang 基础(26)select

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