烂笔头啊烂笔头......
golang是最好的并发语言,拒绝任何反驳。
说到golang的并发,必须要提一个概念--协程
开销:进程>线程>协程 三者之间的关系可自行百度
目前并发比较流行的三种模式:
1、多线程:每个线程一次处理一个请求,线程越多可并发处理的请求数就越多,但是在高并发下,多线程开销会比较大。
2、协程:无需抢占式的调度,开销小,可以有效的提高线程的并发性,从而避免了线程的缺点的部分。
3、基于异步回调的IO模式,说个比较流行的快速建站语言--nodejs,通过事件驱动的方式与异步IO回调,使得服务器持续运转,来支撑高并发的请求
说正题.....
goroutine
goroutine就是golang中的协程,也可以叫做轻量级的现成,与线程比较,创建的成本以及开销都小很多,每个goroutine的堆栈只有几kb,并且堆栈可以根据程序的需要增长和缩小,而线程的堆栈是需要指明和固定的。所以golang从语言层面上支持高并发。
创建格式 go func()
goroutine正确的使用姿势一:主协成结束时,其他协程都会强制结束!
package main
import (
"fmt"
"time"
)
func out() {
fmt.Println("我想先出来")
}
func main() {
go out()
time.Sleep(1 * time.Second)
fmt.Println("好吧,看在sleep哥的份上,让你先出来")
}
执行结果:
我想先出来
好吧,看在sleep哥的份上,让你先出来
如果把time.Sleep注释了,main就不会再等其他协程执行完了,你可能就看不到out的输出了。
goroutine正确的使用姿势二:不同的goroutine之间不会相互影响
package main
import (
"fmt"
"strconv"
"time"
)
func PrintMany() {
for i := 1; i <= 3; i++ {
time.Sleep(250 * time.Millisecond)
fmt.Println("打印第" + strconv.Itoa(i) + "个")
}
}
func PrintSingle() {
fmt.Println("我就打印一个")
}
func main() {
go PrintMany()
go PrintSingle()
time.Sleep(2 * time.Second)
fmt.Println("我是最后一个")
}
执行结果:
我就打印一个
打印第1个
打印第2个
打印第3个
我是最后一个
PrintMany里面有Sleep,是否会导致第二个goroutine阻塞或者等待呢?no。因为两个goroutine之间不会相互影响,main会继续按顺序执行下去
有疑问加站长微信联系(非本文作者)