加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang channel 的使用

发布时间:2020-12-16 09:41:53 所属栏目:大数据 来源:网络整理
导读:本文对channel使用中的几个疑惑,以例子的形式加以说明。 普通channel 缺省情况下,发送和接收会一直阻塞着,直到另一方准备好. 例如: package mainimport ( "fmt" "time" )var ch1 chan boolfunc main(){ ch1 = make(chan bool) go reader() go writer() s

本文对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后就位。






<div class="se-preview-section-delimiter"></div>

##带buffer的channel

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

例1:




<div class="se-preview-section-delimiter"></div>

// 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:




<div class="se-preview-section-delimiter"></div>

// 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/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读