并发与并行
go是支持并发的语言。
并发的程序往往是在单核中交替运行的(通信开销小),并行的程序往往是多核同时运行的(通信开销大)。
Go 协程(Goroutine)
Go 协程是与其他函数或方法一起并发运行的函数或方法。Go 协程可以看作是轻量级线程。与线程相比,创建一个 Go 协程的成本很小。
package main
import (
"fmt"
"time"
)
func hello() {
fmt.Println("Hello world goroutine")
}
func main() {
go hello()
time.Sleep(1 * time.Second)
fmt.Println("main function")
}
go hello()
启动了一个新的 Go 协程。现在 hello()
函数与 main()
函数会并发地执行。
启动一个新的协程时,协程的调用会立即返回。与函数不同,程序控制不会去等待 Go 协程执行完毕。在调用 Go 协程之后,程序控制会立即返回到代码的下一行,忽略该协程的任何返回值。
主函数会运行在一个特有的 Go 协程上,它称为 Go 主协程(Main Goroutine)。如果 Go 主协程终止,则程序终止,于是其他 Go 协程也不会继续运行。
信道(channel)
信道来实现 Go 协程间的通信。
package main
import (
"fmt"
)
func hello(done chan bool) {
fmt.Println("Hello world goroutine")
done <- true
}
func main() {
done := make(chan bool)
// var done chan bool
go hello(done)
data := <-done
// 也可以不赋值直接丢弃结果
// <-done
fmt.Println