一、协程
查看CPU数目
import ( "fmt" "runtime" ) func main() { num := runtime.NumCPU() fmt.Print(num) }
二、管道
管道用来在多个协程间进行通信
初始化分配
//使用make的类型 slice map chan //存放int类型的通道 //这种定义方式只定义,未分配内存的(未初始化) var ch1 chan int //初始化并分配内存 ch2:=make(chan int) //存进通道 ch2<-3 //从通道中取出 ret2:=<-ch2 //直接打印报错了---fatal error: all goroutines are asleep - deadlock! print(ret2)
开辟容量
//如果想要使用,需要加容量 ch3:=make(chan int,1) ch3<-108 ret3:=<-ch3 print(ret3)
不能存放超过通道容量的数量
ch3:=make(chan int,1) ch3<-108 //定义了一个容量,确试图存放第二个数据进去 //报-fatal error: all goroutines are asleep - deadlock! ch3<-99
取出的数量超过通道内存放的数量报错
ch3:=make(chan int,1) ch3<-108 ret3:=<-ch3 //只有一个容量,确想要存放两个数据进去 //报错--fatal error: all goroutines are asleep - deadlock! ret4:=<-ch3 print(ret3) print(ret4)
取出超过通道内存放的数量就会报错,不管你开辟的多大的通道空间
ch:=make(chan int,100) ch<-108 ch<-88 ret1:=<-ch ret2:=<-ch //fatal error: all goroutines are asleep - deadlock! ret3:=<-ch println(ret1) println(ret2) println(ret3)
关闭通道
ch:=make(chan int,100) ch<-108 ch<-88 ret1:=<-ch println(ret1) //关闭通道 close(ch) //可以取出数据 ret2:=<-ch println(ret2) //如果取出的数据超过了存放的数量, //不会报错,取出的值是该类型的默认值,例如存放int的通道取出的值为0 ret3:=<-ch println(ret3) //关闭了的通道不允许再存放值 //报错--panic: send on closed channel ch<-99
ch:=make(chan int,100) ch<-108 ret1:=<-ch println(ret1) //关闭通道 close(ch) //关闭一个已经关闭的通道会报错 //panic: close of closed channel close(ch)
通道数量与容量
ch:=make(chan int,10) ch<-88 //通道中元素的数量 println(len(ch))//1 <-ch println(len(ch))//0 //通道总容量 println(cap(ch))//10
判断通道关闭
func main() { ch:=make(chan int,10) go test(ch) //编译一个未关闭的通道报错,fatal error: all goroutines are asleep - deadlock! //遍历一个关闭的通道,可以正常向下执行 for ch :=range ch{ println(ch) } println("main end") } func test(ch chan int) { for i:=0;i<10;i++ { ch<-i } //close(ch) }
或者使用for 循环
for{ ret,ok:=<-ch if !ok{ break } println(ret) }
无缓冲通道
chan不开辟容量
无缓冲通道必须要保证,往通道存放的时候,程序必须也正在向外取该通道的数据
package main func main() { ch:=make(chan int) // go test(ch) ch<-10 println("main方法结束") } //有可能这个方法还没执行完,主程序就结束了。 func test(ch chan int) { println("test方法开始") //如果ch没有数据,则阻塞到当前位置 //有数据时向下执行 ret:= <-ch println(ret) println("test方法结束") }
有缓冲通道
?????
func main() { ch:=make(chan int,10) // ch<-99 go test(ch) ch<-88 time.Sleep(1000) println("main方法结束") } //有可能这个方法还没执行完,主程序就结束了。 func test(ch chan int) { //println("test方法开始") //如果ch没有数据,则阻塞到当前位置 //有数据时向下执行 ret:= <-ch println(ret) println("test方法结束") }