Go语言的线程模型-Goroutine机制

  大多数Go语言的使用者认为Go语言是互联网时代的C语言,为应用而生,当然我也这么觉得哈哈哈,听君一席话真是如听君一席话。
  目前可以实现并发执行的模型主要有四种,多进程、多线程、基于回调的非阻塞/异步IO、协程。

  • 多进程。多进程是在操作系统层面进行并发的基本模式。同时也是开销最大的模式。在Linux平台上,很多工具链正是采用这种模式在工作。比如某个Web服务器,它会有专门的进程负责网络端口的监听和链接管理,还会有专门的进程负责事务和运算。这种方法的好处在于简单、进程间互不影响,坏处在于系统开销大,因为所有的进程都是由内核管理的。

  • 多线程。多线程在大部分操作系统上都属于系统层面的并发模式,也是我们使用最多的最有效的一种模式。目前,我们所见的几乎所有工具链都会使用这种模式。它比多进程的开销小很多,但是其开销依旧比较大,且在高并发模式下,效率会有影响。

  • 基于回调的非阻塞/异步IO。这种架构的诞生实际上来源于多线程模式的危机。在很多高并发服务器开发实践中,使用多线程模式会很快耗尽服务器的内存和CPU资源。而这种模式通过事件驱动的方式使用异步IO,使服务器持续运转,且尽可能地少用线程,降低开销,它目前在Node.js中得到了很好的实践。但是使用这种模式,编程比多线程要复杂,因为它把流程做了分割,对于问题本身的反应不够自然。

  • 协程。协程(Coroutine)本质上是一种用户态线程,不需要操作系统来进行抢占式调度,且在真正的实现中寄存于线程中,因此,系统开销极小,可以有效提高线程的任务并发性,而避免多线程的缺点。使用协程的优点是编程简单,结构清晰;缺点是需要语言的支持,如果不支持,则需要用户在程序中自行实现调度器。目前,原生支持协程的语言还很少。

  • Go语言就是原生支持协程的语言,Go语言的线程用过的都知道是由go关键字来开启,由channel来完成线程之间的通信,那么再底层是由什么框架来实现的呢?
  • Go语言的线程模型实际是协程的一种实现,叫goroutine机制。这个机制可以简单分为四个部分,用户线程,系统线程、用户线程调度器和内核调度器。
  • 其中用户线程由goroutine来维护,简称为G,包含了栈、指针等,系统线程可以简单理解为CPU处理核心,简称为M-Machine,用户现场调度器控制G和M的对应关系,简称为P-Processor,内核调度器调度系统线程和CPU核心的对应关系。为什么说Go语言适用于高并发呢,答案就在这里,因为G可以同时维护多个用户线程,而G可以同时存在多个,P负责调度G与M的对应关系。简单点说就是多个线程对应多个协程,多个协程对应多个系统线程,多个系统线程对应多个核心处理器,从而充分的利用计算资源。
  • 实际工作中,为了方便理解,这里简化了实际流程,P的作用远不止这么简单,核心和系统线程的对应一般也是多对多的。假如我们在两个双核CPU(4个核心)上同时发起了16次运算请求-16个用户线程,这16个x线程将进入4个G,也就是4个goroutine队列,大概如下图

在这里插入图片描述

  • 用户发起的线程进入不同的Goroutine队列,由P来调度G与M的对应,最后再CPU上完成运算。
  • 当然实际上的并发会有很多问题,比如线程阻塞、抢占式调度等问题,这些问题接下来再讨论。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lemon_tttea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值