通道Channel | 青训营

49 阅读2分钟

go并发

Go 是通过 channel 来回传递数据的。 此方法意味着只有一个goroutine 有权访问数据,设计上不存在争用条件。 Go 的方法可以总结为:“不是通过共享内存通信,而是通过通信共享内存。”

Channel介绍

在 go 语言中,channel 就是 goroutine 之间通过通信来共享内存的手段。 channel 也作为一个队列,会保证数据收发顺序总是按照先入先出的原则进行,可以看作 go 程序内部的一个 FIFO 队列,一些 goroutine 向其中生产数据,另外一些消费数据,同时也会保证同一时刻有且仅有一个goroutine访问channel来收发数据。

创建线程

func main(){
    login()
    go launch()
}

#Channel的类型

  • chan T 双向 channel ,既能接收值又能发送值
  • chan<- T send-only channel,发送数据格式:只能往里写(chan是箭头的终点)
  • <-chan T receive-only channel,接收数据格式:只能从里读(chan是箭头的起点) 在函数中使用即:
func foo(ch1 <-chan int)  // 只能从 ch1 里读
func bar(ch2 chan<- int)  // 只能往 ch2 里写

一般来说,用make创建channel

ch1 := make(chan int, 10)  // buffered channel, cap = 10
ch2 := make(chan int) // unbuffered channel, cap = 0 (make chan 函数第二参数默认值为 0)
var ch3 chan int  // nil 是 chan 的零值(zero value)

向Channel发送信息

ch <- v
  • v 需要和 ch 声明的元素类型相同,例如
  • <- 是 channel-send 即 channel 发送操作符
  • 这里的 ch 不能是 receive-only channel

Channel分无缓冲和有缓冲 用make创建channel,默认的channel是无缓冲的channel,但有些情况下,只有存在接收操作时,它们才接受发送操作。 否则,程序将永久被阻止等待。 但是为了实现并发,有时候不需要这样的等待,所有有缓冲channel 有缓冲 channel 的行为类似于队列。 创建 channel 时,可以限制此队列的大小,如下

ch := make(chan string, 10)

无缓冲与有缓冲channel的区别

无缓冲 channel 同步通信。 它们保证每次发送数据时,程序都会被阻止,直到有人从 channel 中读取数据。使用无缓冲 channel 时,可以控制可并发运行的 goroutine 的数量。

相反,有缓冲 channel 将发送和接收操作解耦。 它们不会阻止程序,但你必须小心使用,因为可能最终会导致死锁