什么是高并发
https://studygolang.com/articles/10939#reply0
**重点内容**Go语言高并发优势的原因:
goroutine每个实例占据的栈内存极小,故减少了创建和销毁的开销,是制造Go号称的高并发的根本原因。
并发不是并行
并发:主要由切换时间片来实现”同时”运行
并行:直接利用多核实现多线程的运行,但是Go可以设置使用核数,以发挥多核计算机的能力
goroutine奉行通过通信来共享内存,而不是共享内存来通信
当main()结束的时候他不会管你的线程是否结束
package main
import "fmt"
func Go(){
fmt.Println("GO GO GO!")
}
func main(){
go Go()
}
例如如上函数就不会有输出
Channel
goroutine沟通的桥梁
channel创建出来都是双向的
但是可以把她设置成单向的
引用类型也就是传入数据的改变会影响原数据
默认是阻塞的
小例子1
package main
import "fmt"
func main(){
c:=make(chan bool)
go func(){
fmt.Println("GO GO GO!")
c<-true//store
}()
<-c//get,will wait for goroutine's store or it will block
}
迭代取
package main
import "fmt"
func main(){
c:=make(chan bool)
go func(){
fmt.Println("GO GO GO!")
c<-true//store
close(c)//close the channel
}()
for v:=range c{//won't stop until close the channel successful
fmt.Println(v)
}
}
关于缓存
可以设置缓存,在未被填满前不会发生阻塞,也就是说异步的,无缓存是同步阻塞的
有缓冲:放入数据的操作c<- 0先于取数据操作 <-c
无缓冲:必须保证取操作<-c 先于放操作c<- 0
http://studygolang.com/articles/152
package main
import "fmt"
import "runtime"
func main(){
runtime.GOMAXPROCS(runtime.NumCPU())//return the num of CPU
c:=make(chan bool,10)
for i:=0;i<10;i++{
go Go(c,i)
}
for i:=0;i<10;i++{
<-c
}
}
func Go(c chan bool,index int) {
a:=1
for i:=0;i<10000000;i++{
a+=i
}
fmt.Println(index,a)
c<-true
}
关于sync包
package main
import "fmt"
import "runtime"
import "sync"
func main(){
runtime.GOMAXPROCS(runtime.NumCPU())//return the num of CPU
wg:=sync.WaitGroup{}
wg.Add(10)
for i:=0;i<10;i++{
go Go(&wg,i)
}
wg.Wait()
}
func Go(wg *sync.WaitGroup,index int) {
a:=1
for i:=0;i<10000000;i++{
a+=i
}
fmt.Println(index,a)
wg.Done()
}
多个Channel的发送与接收Select
package main
import "fmt"
func main(){
c1,c2:=make(chan int),make(chan string)
o:=make(chan bool)
go func(){
a,b:=false,false//ensure that only write once to channel
for{
select{
case v,ok:=<-c1:
if !ok{
if !a{
o<-true
a=true
}
break
}
fmt.Println("c1",v)
case v,ok:=<-c2://v and ok are local variable
if !ok&&!b{
if !b{
o<-true
b=true
}
break
}
fmt.Println("c2",v)
}
}
}()
c1<-1
c2<-"hi"
c1<-3
c2<-"hello"
close(c1)
close(c2)
<-o//ensure that there has one routine has finished before the main
}
select作为发送者
package main
import "fmt"
func main(){
c:=make(chan int)
go func(){
for v:=range c{
fmt.Println(v)
}
}()
for{
select{
case c<-0:
case c<-1:
}
}
}
空的selece{}就一直阻塞
关于select设置定时
例子
package main
import "fmt"
import "time"
func main(){
c:=make(chan int)
select{
case v:=<-c:
fmt.Println(v)
case <-time.After(3*time.Second):
fmt.Println("Timeout")
}
}