golang channel 的使用

前端之家收集整理的这篇文章主要介绍了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后就位。






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

原文链接:https://www.f2er.com/go/187600.html

猜你在找的Go相关文章