本节我们来看GO语言中的并发。
我们看并发,就不得不学习goroutine,goroutine是Go语言并行设计的核心。goroutine说到底就是线程,但是它比现场更小,几十个goroutine可能体现就是五六个线程,Go语言内部帮我们实现了这些goroutine之间的内存共享。
goroutine是通过Go语言rutime管理的一个线程管理。goroutine通过go关键字实现了,其实就是一个普通函数。
例子01
package main
import (
"fmt"
"rutime"
)
func say(s string){
for i:=0;i<5;i++{
runtime.Gosched()
fmt.Println(s)
}
}
func main(){
go say("world")//开一个新的Goroutines执行
say("hello")//当前Goroutines执行
}
输出:
hello
world
hello
world
hello
world
hello
world
hello
world
Go语言提供了一个很好的通信机制channel。它就是goroutine运行在相同地址空间,访问时需要做好同步,之间进行数据通信的。channel可以与Unix shell中的双向管道做类比,通过它发送或者接收值。
创建channel时注意:必须使用make.
ci:=make(chan int)
ci:=make(chan string)
cf:=make(chan interface{})
channel通过操作符<-来接收和发送数据。
ch<-v //发送V到channel ch.
v:=<-ch //从ch中接收数据,并赋值给V
例子02
package main
func sum(a []int,c chan int){
sum:=0
for _,v:=range a{
sum+=v
}
c<-sum
}
func main(){
a:=[] int{7,2,8,-9,4,0}
c:=make(chan int)
go sum(a[:len(a)/2],c)
go sum(a[len(a)/2:],c)
x,y:=-c,<-c
fmt.Println(x,y,x+y)
}
上面介绍的只有一个channel的情况,如果存在多个channel,我们该如何操作呢?Go语言中提供了一个关键字select,通过select可以监控channel上的数据流动。
例子03:
package main
import "fmt"
func fibonacci(c,quit chan int){
s,y:=1,1
for{
select{
case c<-x:
x,y=y,x+y
case<-quit:
fmt.Println("quit")
return
}
}
}
func main(){
c:=make(chan int)
quit:=make(chan int)
go func(){
for i:=0;i=10;i++{
fmt.Println(<-c)
}
quit<-0
}()
fibonacci(c,quit)
}
请开始你的表演,践行,践行,再践行。未完待续。。。