zoukankan      html  css  js  c++  java
  • golang channel 的使用

    本文对channel使用中的几个疑惑,以例子的形式加以说明。

    普通channel

    缺省情况下,发送和接收会一直阻塞着,直到另一方准备好.
    例如:

    package main
    
    import (
    
            "fmt"
            "time"
    
    )
    
    var ch1 chan bool
    
    func main(){
    
    
            ch1 = make(chan bool)
    
            go reader()
            go writer()
    
            select {
            }
    
    }
    
    func writer() {
    
            time.Sleep(10*time.Second)
            for {
    
                    ch1 <- true
                    fmt.Println("write one ...")
            }
    
    }
    
    
    
    func reader() {
    
            for {
                    select {
                    case <-ch1:
                            fmt.Println("read one ....")
                    }
    
                    time.Sleep(2*time.Second)
            }
    }
    

    output:

    $ ./chan1.exe
    write one ...
    read one ....
    read one ....
    write one ...
    read one ....
    write one ...
    read one ....
    write one ...

    从执行结果看,reader卡住,直到writer sleep后就位,才继续执行。反之,让reader先睡眠,writer也会卡住,直到reader sleep后就位。

    带buffer的channel

    带buffer的channel可以减少阻塞,对一些需要只保持有限个执行过程的情景很有用。

    例1:

    // reader wait, until writer begin to write.
    package main
    
    import (
    
            "fmt"
            "time"
    
    )
    
    var ch1 chan bool
    
    func main(){
    
    
            ch1 = make(chan bool, 1)
    
            go reader()
            go writer()
    
            select {
            }
    
    }
    
    func writer() {
    
            time.Sleep(10*time.Second)
            for {
    
                    ch1 <- true
                    fmt.Println("write one ...")
            }
    
    }
    
    
    
    func reader() {
    
            for {
                    select {
                    case <-ch1:
                            fmt.Println("read one ....")
                    }
    
                    time.Sleep(2*time.Second)
            }
    }
    

    这种情景中,先让writer睡眠,reader此时卡住,直到writer就位,也就是说,带buffer,如果没有数据写入,reader也是卡住的。

    例2:

    // writer write one, then wait
    package main
    
    import (
    
            "fmt"
            "time"
    
    )
    
    var ch1 chan bool
    
    func main(){
    
    
            ch1 = make(chan bool, 1)
    
            go reader()
            go writer()
    
            select {
            }
    
    }
    
    func writer() {
    
            for {
    
                    ch1 <- true
                    fmt.Println("write one ...")
            }
    
    }
    
    
    
    func reader() {
    
            time.Sleep(10*time.Second)
            for {
                    select {
                    case <-ch1:
                            fmt.Println("read one ....")
                    }
    
                    time.Sleep(2*time.Second)
            }
    }
    

    如果先让reader睡眠,writer直接向channel写,可以看到writer可以写入一个数据,然后卡住,直到reader就位,才可以继续写。
    也就是说,带一个buffer的channel,可以在reader就位前首先写入一个数据。

    参考

    http://colobu.com/2016/04/14/Golang-Channels/

  • 相关阅读:
    Beetle在TCP通讯中使用协议分析器和自定义协议对象
    Beetle在TCP通讯中使用AMF3协议和Flash通讯
    发布一个TCP 吞吐性能测试小工具
    替书仙澄清一些东西,并且对无知的人谈谈网络追踪
    2006年4月1日测彩研究
    构建工具研究:该死的Maven的j2me构建
    2006年4月2日测彩研究
    Eclipse的插件代码折叠
    JAVA这堆IDE........无言
    假如人生不曾相遇(转)
  • 原文地址:https://www.cnblogs.com/lanyangsh/p/7967322.html
Copyright © 2011-2022 走看看