原因:go语言在设计的时候从关键字层面实现了多协程开发。go语言实现了CSP并发模型做为并发基础,底层使用goroutine做为并发实体,goroutine非常轻量级可以创建几十万个实体;实体间通过channel继续匿名消息传递使之解耦,在语言层面实现了自动调度,这样屏蔽了很多内部细节,对外提供简单的语法关键字,大大简化了并发编程的思维转换和管理线程的复杂性。
本教程操作环境:windows7系统、GO 1.18版本、Dell G3电脑。
go的传说
坊间对于Go的传说不可谓不多,“天生支持高并发,执行速度接近C,网络服务接近Nginx……”。其它还好,唯独难理解的是“天生支持高并发”,尤其是“天生”二字,着实让人感到满满的高端和神秘。
我们先来看看在go中实现并发操作到底有多简单,来看代码:
func main() { go add(3,6) go add(1,6) time.Sleep(time.Second)}func add(a int,b int) { result := a+b fmt.Println(result)}
go关键字实现了协程开辟调用,如果不进行等待,主线程结束,协程就会马上结束。
go的并发
其实go语言中的goroutine就是参考的(Communicating Sequential Process)模型,原始的CSP中channel里的任务都是立即执行的,而go语言为其增加了一个缓存,即任务可以先暂存起来,等待执行进程准备好了再逐个按顺序执行。
但其实go语言并没有完全实现了CSP模型的所有理论,仅仅是借用了 process和channel这两个概念。process是在go语言上的表现就是 goroutine 是实际并发执行的实体,每个实体之间是通过channel通讯来实现数据共享。
1)goroutine
Goroutine 是go实际并发执行的实体,它底层是使用协程(coroutine)实现并发,coroutine是一种运行在用户态的用户线程,go底层选择使用coroutine的出发点是因为,它具有以下特点:
- 用户空间 避免了内核态和用户态的切换导致的成本
- 可以由语言和框架层进行调度
- 更小的栈空间允许创建大量的实例
2)channel
go中使用了 CSP中的 channel 。channel 是被单独创建并且可以在进程之间传递,它的通信模式类似于 boss-worker 模式的,一个实体通过将消息发送到channel 中,然后又监听这个 channel 的实体处理,两个实体之间是匿名的,这个就实现实体中间的解耦,其中 channel 是同步的一个消息被发送到 channel 中,最终是一定要被另外的实体消费掉的,在实现原理上其实是一个阻塞的消息队列。
3)调度器
goroutine是在golang层面提供了调度器,在调度器加入了steal working 算法 ,goroutine是可以被异步抢占,因此没有函数调用的循环不再对调度器造成死锁或造成垃圾回收的大幅变慢。并且go对网络IO库进行了封装,屏蔽了复杂的细节,对外提供统一的语法关键字支持,简化了并发程序编写的成本。
总结
Golang实现了 CSP 并发模型做为并发基础,底层使用goroutine做为并发实体,goroutine非常轻量级可以创建几十万个实体。实体间通过 channel 继续匿名消息传递使之解耦,在语言层面实现了自动调度,这样屏蔽了很多内部细节,对外提供简单的语法关键字,大大简化了并发编程的思维转换和管理线程的复杂性。
一句话总结:go语言在设计的时候从关键字层面实现了多协程开发,好像语言天生支持高并发一样。
以上就是go语言支持高并发的原因是什么的详细内容,更多请关注php中文网其它相关文章!