goroutine
goroutine是Go内置的轻量级线程,它的调度由Go运行时管理,调用函数时前面加上关键字go就可以让函数在goroutine中执行。
func print123(){
for i:=0;i<3;i++{
time.Sleep(time.Millisecond*100)
fmt.Println(i+1)
}
}
func main(){
go print123()
print123()//1 1 2 2 3 3
time.Sleep(time.Second*5)
}
通道
通道可通过一个指定类型的值来传递数据,<-chan表示只读通道,只能从通道中接受数据,chan<-表示只写通道,只能向通道发送数据,如果未指定方向,则为双向通道。
默认情况下,通道是不带缓冲区的,向无缓冲区的通道发送数据时会阻塞直到从通道读取数据,从无缓存区的通道读取数据时会阻塞直到向通道写入了数据。
向有缓冲区的通道发送数据时不会阻塞直到缓冲区占满为止,从有缓冲区的通道读取数据时不会阻塞直到缓存区已无数据为止。
通道默认值为nil, 使用内置函数make创建通道:
func main(){
//双向通道
var ch1 chan int=make(chan int)
//只读通道,只能从通道中接受数据
ch2:=make(<-chan int)
//只写通道,只能向通道发送数据
ch3:=make(chan<- int)
//带缓存区的通道
ch4:=make(chan int,100)
}
在goroutine中计算数字之和然后写入通道:
func printSum(input [] int,result chan <- int){
sum:=0
for _,value:=range input{
sum+=value
}
result <- sum
}
func main(){
c:=make(chan int)
go printSum([]int{3,4,5},c)
result,ok:=<-c
if ok{
fmt.Println(result)//12
}
}
向有缓存区的通道写入数据后读取数据:
func main(){
c:=make(chan int,2)
c <- 1
c <- 2
fmt.Println(<-c)//1
fmt.Println(<-c)//2
}
select
select是Go中的一个控制结构,类似于switch语句,每个case都是一个通道的通信,如果某个case可以运行,select会随机选择一个运行;如果没有case可运行,则执行default子句,如果没有default子句,select将阻塞直到某个case可以运行。
func print123(exitSignal <- chan int){
for{
select {
case value,ok:=<-exitSignal:
if (ok && value==0){
fmt.Println("received exit signal,exit!")
return
}
default:
fmt.Println("123")
time.Sleep(time.Second)
}
}
}
func main() {
exitSignal:=make(chan int)
go print123(exitSignal)
time.Sleep(time.Second*5)
fmt.Println("send exit signal")
exitSignal <- 0
time.Sleep(time.Second*5)
}
结果:
123
123
123
123
123
send exit signal
received exit signal,exit!
有疑问加站长微信联系(非本文作者)