golang channel 的使用

lanyangsh · · 1000 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

本文对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/


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:lanyangsh

查看原文:golang channel 的使用

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1000 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传