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 将发送和接收操作解耦。 它们不会阻止程序,但你必须小心使用,因为可能最终会导致死锁