写点什么

Go 协程并发之百万级并发「让我们一起 Golang」

用户头像
Regan Yue
关注
发布于: 2 小时前
Go协程并发之百万级并发「让我们一起Golang」

Go 协程并发之百万级并发「让我们一起 Golang」

前面我们介绍了关于Golang的协程并发的一些理论知识,接下来我们上代码,通过代码带大家了解一下Go的协程并发,体验Go的百万级并发。


我们先来了解一下进程、线程、协程的区别吧!


进程有自己独立的堆和栈,而线程虽然拥有独立的栈,但是它的堆是共享的。而我们这里要讲的协程和线程是一样的,也是只共享堆,而不共享栈。但是协程不像进程和线程那样由操作系统调度,而是由程序员来调度,这样就可以节省资源,提高性能。


下面来看看主协程和一条协程在并发执行时的表现吧!


func main()  {  go func() {    for{      fmt.Println("i am coroutine")      time.Sleep(time.Second)    }  }()
for{ fmt.Println("我是主协程") time.Sleep(time.Second) }}
复制代码


他们运行结果是:


我是主协程i am coroutinei am coroutine我是主协程我是主协程i am coroutinei am coroutine我是主协程i am coroutine我是主协程
复制代码


我们可以看到,他们并不是顺序执行的,而是并发执行的,这就是协程并发。


func main() {  //但是开启100条小协程是主协程干的  //迅速开启100条小协程  for i:=0;i<10;i++{    go doSomething("面包人"+strconv.Itoa(i))  }
for{ fmt.Println("我是主协程") time.Sleep(time.Second) }}
func doSomething(grname string) { for{ fmt.Println("来了一车",grname) time.Sleep(time.Second) }}
复制代码


来了一车 面包人0来了一车 面包人7来了一车 面包人8我是主协程来了一车 面包人2来了一车 面包人6来了一车 面包人3来了一车 面包人1来了一车 面包人5来了一车 面包人9来了一车 面包人4来了一车 面包人0来了一车 面包人8来了一车 面包人1来了一车 面包人2来了一车 面包人4来了一车 面包人7来了一车 面包人3来了一车 面包人9来了一车 面包人5我是主协程来了一车 面包人6来了一车 面包人1来了一车 面包人4
复制代码


这里体验的是 11 条协程并发。是主协程唤起了十条协程,然后才有一车车面包人来打你。因此主协程是那个打电话喊面包人打你的人。也就是说主协程开启了 10 条协程。但是这十一条协程是并发的,他们不是顺序执行的。虽然是并发执行的,但是在微观上每次还是只能执行一条协程,但是他们的执行顺序和创建顺序是不一致的。


然后将


for i:=0;i<10;i++{    go doSomething("面包人"+strconv.Itoa(i))  }
复制代码


改为


for i:=0;i<1000000;i++{    go doSomething("面包人"+strconv.Itoa(i))  }
复制代码


这就是百万级并发了!


一个主协程可以喊 100 万车面包人打你。


经过测试,程序持续 1 分钟都没有崩溃。事实证明,执行协程只需要消耗极少的内存和 CPU 资源,所以我们可以创建一百万条协程。16G 内存的电脑,用 JAVA,C 来做并发,差不多也就千级并发,而用 GO 语言,通过管道可以让并发能力得到很大提升,我们这里实现了百万级并发。


goroutine 是协作式调度的,而 Java 等的使用的线程是抢占式调度的。

发布于: 2 小时前阅读数: 7
用户头像

Regan Yue

关注

还未添加个人签名 2020.08.12 加入

还未添加个人简介

评论

发布
暂无评论
Go协程并发之百万级并发「让我们一起Golang」