Golang-缓冲通道&定向通道

1.非缓冲通道:发送和接收到一个未缓冲的通道是阻塞的;一次发送操作对应一次接收操作;对于一个goroutine来讲,它的一次发送,在另一个goroutine接受之前都是阻塞的,同样的,对于接收来讲,在另一个goroutine发送之前,它也是阻塞的

2.缓冲通道:指一个通道,带有一个缓冲区。发送到一个缓冲通道只有在缓冲区满时才被阻塞。类似地,从缓冲通道接收的信息只有在缓冲区为空时才会被阻塞

  • 语法:ch := make(chan type, capactity);capactity应该大于零,以便通道具有缓冲区;无缓冲通道的容量为0,因此之前创建通道时省略了容量参数
func main() {
    ch3 := make(chan string, 4)
    go sendData(ch3)

    for{
        v, ok := <-ch3
        if !ok{
            fmt.Println("读完了。。。", ok)
            break
        }
        fmt.Println("读取的数据是:", v)

    }

    fmt.Println("main...over...")
}

func sendData(ch chan string)  {
    for i:= 0; i<10; i++ {
        ch <- "数据" + strconv.Itoa(i)
        fmt.Printf("子goroutine中发送的第 %d 个数据\n", i)
    }
    close(ch)
}

3.定向通道

  • 双向通道:一个goroutine可以向通道发送数据,也可以接收数据
双向通道:
        chan
            chan <- data,发送数据,写出
            data <- chan,获取数据,读取
单向通道:定向通道
        chan <- T, 只支持写
        <- chan T, 只支持读
ch1 := make(chan string)

    done := make(chan bool)
    go sendData(ch1, done)

    data := <- ch1 //读取
    fmt.Println("子goroutine传来的数据是:", data)

    ch1 <- "我是main的数据" //发送数据

    <- done//因为阻塞,所以会等待子goroutine的 通道done发送数据
    fmt.Println("main...over...")

    //time.Sleep(1)

}

func sendData(ch1 chan string, done chan bool)  {
    ch1 <- "我是lzc" //发送

    data := <- ch1 //读取数据
    fmt.Println("main goroutine传来的数据:", data)

    done <- true
}
  • 定向通道也叫单向通道
单向:单向
            chan <- T, 只支持写
            <- chan T, 只读
ch2 := make(chan <- int)//单向,只能写,不能读
ch2 <- 100
data := <- ch2
invalid operation: <-ch2 (receive from send-only type chan<- int)


ch3 := make(<- chan int)//单向,只能读,不能写
ch3 <- 100
invalid operation: ch3 <- 100 (send to receive-only type <-chan int)

标签: Channel

添加新评论