Go语言 之单向channel及应用

一、单向通道

单向channel变量的声明非常简单,如下:

var ch1 chan int       // ch1是一个正常的channel,是双向的

var ch2 chan<- float64 // ch2是单向channel,只用于写float64数据

var ch3 <-chan int     // ch3是单向channel,只用于读int数据

可以将 channel 隐式转换为单向队列,只收或只发,不能将单向 channel 转换为普通 channel:

    c := make(chan int, 3)

    var send chan<- int = c // send-only

    var recv <-chan int = c // receive-only

    send <- 1

    //<-send //invalid operation: <-send (receive from send-only type chan<- int)

    <-recv

    //recv <- 2 //invalid operation: recv <- 2 (send to receive-only type <-chan int)

    //不能将单向 channel 转换为普通 channel

    d1 := (chan int)(send) //cannot convert send (type chan<- int) to type chan int

    d2 := (chan int)(recv) //cannot convert recv (type <-chan int) to type chan int

package main

import (
    "fmt"
)

//写入通道
func Product(c chan<- int) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    //关闭通道
    close(c)
}

//读取通道
func Customer(c <-chan int) {
    //阻塞等待通道传输数据或关闭
    for data := range c {
        fmt.Println(data)
    }
}

func main() {
    c := make(chan int)
    //创建协程
    go Product(c)
    Customer(c)
    fmt.Println("done")
}

 二、生产者消费者模型

单向channel最典型的应用是“生产者消费者模型”

所谓“生产者消费者模型”: 某个模块(函数等)负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、协程、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。

单单抽象出生产者和消费者,还够不上是生产者/消费者模型。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。大概的结构如下图:

缓冲区的作用:

1、解耦

2、处理并发

3、缓存数据

 

posted @ 2019-07-04 13:43  样子2018  阅读(1290)  评论(0编辑  收藏  举报