Go语言的并发是基于 goroutine 的,goroutine 类似于线程,但并非线程。可以将 goroutine 理解为一种虚拟线程。Go语言运行时会参与调度 goroutine,并将 goroutine 合理地分配到每个 CPU 中,最大限度地使用CPU性能。
Go 程序从 main 包的 main() 函数开始,在程序启动时,Go 程序就会为 main() 函数创建一个默认的 goroutine。

下面我们来看一个例子,在线演示:https://play.golang.org/p/U9U-qjuY0t1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package main
import ( "fmt" "time" )
func main() { go runing() go func() { fmt.Println("喜特:" + time.Now().String()) }()
time.Sleep(5 * time.Second) }
func runing() { fmt.Println("法克:" + time.Now().String()) time.Sleep(3 * time.Second) }
输出: 法克:2009-11-10 23:00:00 +0000 UTC m=+0.000000001 喜特:2009-11-10 23:00:00 +0000 UTC m=+0.000000001
|
执行结果说明fuck函数中的sleep三秒并没有影响喜特
的输出。
如果说 goroutine 是Go语言程序的并发体的话,那么 channel 就是它们之间的通信机制。一个 channel 是一个通信机制,它可以让一个 goroutine 通过它给另一个 goroutine 发送值信息。每个 channel 都有一个特殊的类型,也就是 channel 可发送数据的类型。一个可以发送 int 类型数据的 channel 一般写为 chan int。
下面我们利用goroutine+channel来实现一个生产消费者模型,示例代码如下,在线执行:https://play.golang.org/p/lqUBugLdU-I
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package main
import ( "fmt" "time" )
func main() { channel := make(chan int64)
go producer(channel)
consumer(channel) }
func producer(channel chan<- int64) { for { channel <- time.Now().Unix() time.Sleep(time.Second) } }
func consumer(channel <-chan int64) { for { timestamp := <-channel fmt.Println(timestamp) } }
输出为如下:(每秒钟打印一次) 1257894000 1257894001 1257894002 1257894003
|