深入浅出golangGolang 开发者Golang 入门资料+笔记

39. channel管道

2017-08-27  本文已影响118人  厚土火焱

channel 是有类型的管道,channel 的操作符是 <- ,可以用来发送或接收值。

ch <- v    //赋值给管道,管道接收值
v := <- ch    //管道发送值

管道的使用也是必须创建的。创建的方式是

ch := make(chan int)

管道默认情况下,在另一端准备好之前,发送和接收都会堵塞。这使得 goroutine 可以在没有明确的锁的情况下进行同步。
看一个完整的例子

package main

import "fmt"

func sum(a []int, c chan int)  {
    sum := 0
    for _, v := range a{
        sum += v
    }
    c <- sum
}
func main() {
    a := []int{2, 0, 1, 7, 0, 8, 2, 7, 1, 7, 4}
    c := make(chan int)
    go sum(a[:len(a)/2], c)
    go sum(a[len(a)/2:], c)
    x, y := <-c, <-c
    fmt.Println(x, y, x + y)
}

运行结果

29 10 39

channel 是可以设置缓冲的,向有缓冲的 channel 发送数据的时候,在缓冲区满的时候才会阻塞。而当缓冲区为空的时候,接收操作会阻塞。
设置 channel 缓冲通道数量的方式如下

ch := make(chan int, 100)

这个通道数量是100。
展示一个有缓冲区的例子

package main

import "fmt"

func main() {
    ch := make(chan int, 2)
    ch <- 100
    ch <- 5
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

运行结果是

100
5

本例设置了缓冲数为 2。意思是在一个 goroutine 里可以有两个传值操作,在通道值被接收前通道会被占满。如果有第三个值传入通道会发生失败。

    ch <- 100
    ch <- 5
    ch <- 77

增加一个传入值,再运行看看,会得到如下结果

fatal error: all goroutines are asleep - deadlock!
上一篇下一篇

猜你喜欢

热点阅读