大家都在说go是一门适合并发的语言,它的优势你真的知道吗?

改变策略,先说答案再说分析:

怎么就适合并发了?

确实是这样的,但是原因可能和你认为的不太一样,大家都知道go关键字可以快速开启协程也就是轻量级线程,携程也拥有自己的栈空间,且go为我们提供了可伸缩等一系列内存优化策略,还提供了channel作为goroutine通信的基础,但是这就适合并发场景了吗?

其实不然,设想一个场景,我们在java并发编程中,使用onthread-onconnect的经典io多路复用模型时不足在什么地方,答案是线程的上下文切换,设想我们一个线程触发了io中断时因为java的线程模型是一对一的混合线程模型,所以会触发系统级io中断陷入内核态,如果多个connect同时出发那么系统上下文切换的开销是巨大的,这也就是java的nio模型的不足之处(当然可以通过reactor模型去优化,这里是举反例说明)。

说回到go。go的并发编程优势就体现在这里,根据GPM模型分析当我们一个goroutine触发了中断G就会被park,当前线程会被中断,但是我们后续的goroutine不会受到影响,因为GPM会把其他goroutine切换mechine去执行,那么提现到操作上就是仿佛go就给我们实现了非阻塞机制,假设我们自己去实现一套事件驱动框架呢?当然性能只会更加可控更加高效。

但是这里有个特殊情况那就是网络IO,golang底层实际上实现了netpoller底层封装了epoll/kqueue实现事件驱动机制,所以仅仅会park住G而不会使M被中断。

最后渗透一点GPM的概念

这里引用一张图片

其实这个图片已经很清晰了,当然延续上文,我们在某个线程中断挂起后实际上是会产生任务窃取的,也就是说 会触发摘除创建新的线程或加入空闲的M继续服务,加上每个goroutine的时间片是非常短的期间空闲线程会发生窃取,所以几乎可以做到阻塞无感。当然goroutine实际上实现的是一个协程,可以简单理解为一个用户级线程,调度器在切换goroutine的时候并不会陷入内核态,所以自然要高效很多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值