go快速学习_Channel 管道

2019-07-17  本文已影响0人  卖毛玉的小贩

Channel的基本概念

Channal就是用来通信的,像Unix下的管道一样,
它的操作符是箭头" <-" , 箭头的指向就是数据的流向

ch <- v // 发送值v到Channel ch中
v := <-ch // 从Channel ch中接收数据,并将数据赋值给v

下面的程序演示了一个goroutine和主程序通信的例程。

package main

import "fmt"

func main() {
    //创建一个string类型的channel
    channel := make(chan string)

    //创建一个goroutine向channel里发一个字符串
    go func() { channel <- "hello" }()

    msg := <- channel
    fmt.Println(msg)
}

chan为先入先出的队列,有三种类型,双向,只读,只写,分别为"chan","chan<-","<-chan"
初始化时候,可以指定容量make(chanint,100);容量(capacity)代表Channel容纳的最多的元素的数量

Channel的阻塞

channel默认上是阻塞的,也就是说,如果Channel满了,就阻塞写,如果Channel空了,就阻塞读。于是,我们就可以使用这种特性来同步我们的发送和接收端。

package main

import "fmt"
import "time"

func main() {

    channel := make(chan string) //注意: buffer为1

    go func() {
        channel <- "hello"
        fmt.Println("write \"hello\" done!")

        channel <- "World" //Reader在Sleep,这里在阻塞
        fmt.Println("write \"World\" done!")

        fmt.Println("Write go sleep...")
        time.Sleep(3*time.Second)
        channel <- "channel"
        fmt.Println("write \"channel\" done!")
    }()

    time.Sleep(2*time.Second)
    fmt.Println("Reader Wake up...")

    msg := <-channel
    fmt.Println("Reader: ", msg)

    msg = <-channel
    fmt.Println("Reader: ", msg)

    msg = <-channel //Writer在Sleep,这里在阻塞
    fmt.Println("Reader: ", msg)
}

结果为

Reader Wake up...
Reader:  hello
write "hello" done!
write "World" done!
Write go sleep...
Reader:  World
write "channel" done!
Reader:  channel

总结

go程间通信

同步通信,异步通信

关闭channel

单向channel

Select关键字

多个Channel的select

package main
import "time"
import "fmt"

func main() {
    //创建两个channel - c1 c2
    c1 := make(chan string)
    c2 := make(chan string)

    //创建两个goruntine来分别向这两个channel发送数据
    go func() {
        time.Sleep(time.Second * 1)
        c1 <- "Hello"
    }()
    go func() {
        time.Sleep(time.Second * 1)
        c2 <- "World"
    }()

    //使用select来侦听两个channel
    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }
}

select的使用

上一篇下一篇

猜你喜欢

热点阅读