前面章节,已经看到了 Go
语言设计简单(尤其是其中),接着就是了解一下 Go
的并行程序设计,Go 从语言层面就支持了并行。
Goroutine
goroutine
是 Go
并行设计的核心。
goroutine
就是协程,但是它比线程更小,十几个 goroutine
可能体现在底层就是五六个线程,Go
语言内部帮你实现了这些 goroutine
之间的内存共享。
执行 goroutine
只需极少的栈内存 (大概是 4~5 KB),当然会根据相应的数据伸缩。也正因为如此,可同时运行成千上万个并发任务。goroutine
比 thread
更易用、更高效、更轻便。
goroutine
是通过 Go
的 runtime
管理的一个线程管理器。
goroutine
通过 go
关键字实现了,其实就是一个普通的函数。
go hello(a, b, c)
: 这样就很容易的启动了一个协程来执行一段代码。
func say(s string) {
for i := 0; i < 5; i++ {
runtime.Gosched()
fmt.Println(s)
}
}
func main() {
go say("world") // 开一个新的 Goroutines 执行
say("hello") // 当前 Goroutines 执行
}
我们可以看到 go
关键字很方便的就实现了并发编程。
上面的多个goroutine
运行在同一个进程里面,共享内存数据。 不过设计上我们要遵循:不要通过共享内存来通信,而要通过通信来共享。
Channels
goroutine
运行在相同的地址空间,因此访问共享内存必须做好同步。那么 goroutine
之间如何进行数据的通信呢,Go
提供了一个很好的通信机制 channel
。
channel
可以与 Unix shell
中的双向管道做类比:可以通过它发送或者接收值。
这些值只能是特定的类型: channel
类型。定义一个 channel
时,也需要定义发送到 channel
的值的类型。
注意,必须使用 make
创建 channel
: c := make(chan int)
channel
通过操作符