美文网首页Python
golang协程为什么比线程轻量?

golang协程为什么比线程轻量?

作者: one_zheng | 来源:发表于2019-07-07 16:19 被阅读0次

先理解下进程、线程跟协程的概念:

进程
   计算机的操作系统模式是一种多任务系统,操作系统接管了所有的硬件资源,并且本身运行在一个受硬件保护的级别。所有的应用程序都以进程(process)的方式运行在比操作系统权限更低的级别,每个进程都有自己独立的地址空间,使得进程之间的地址空间相互隔离。CPU由操作系统统一进行分配,每个进程根据进程的优先级的高低都有机会得到CPU,但是如果允许时间超出了一定的时间,操作系统会暂停该进程,将CPU资源分配给其他等待的进程。这种CPU的分配方式即所谓的抢占式,操作系统可以强制剥夺CPU资源并且分配给它认为目前最需要的进程。如果操作系统分配给每个进程的时间都很短,即CPU在多个进程间快速地切换,从而造成了很多进程都在同时运行的假象。

线程
  线程有时被称为轻量级进程(Lightweight Process),是程序执行流的最小单元,一个标准的线程由线程ID,当前指令指针(PC)、寄存器集合和堆栈组成,通常意义上,一个进程🈶一个到多个线程组成,各个线程之间共享程序的内存空间(包括代码段、数据段、堆等)及一些进程级的资源(如打开文件和信号)。一个经典的线程与进程的关系如图1-8所示:

image.png

go协程
  协程(coroutine)是Go语言中的轻量级线程实现,由Go运行时(runtime)管理。

进程、线程、协程的关系和区别:

  • 进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。

  • 线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度(标准线程是的)。

  • 协程和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。

并发与并行(Concurrency and Parallelism)

  并发是指程序的逻辑结构。非并发的程序就是一根竹竿捅到底,只有一个逻辑控制流,也就是顺序执行的(Sequential)程序,在任何时刻,程序只会处在这个逻辑控制流的某个位置。而如果某个程序有多个独立的逻辑控制流,也就是可以同时处理(deal)多件事情,我们就说这个程序是并发的。这里的“同时”,并不一定要是真正在时钟的某一时刻(那是运行状态而不是逻辑结构),而是指:如果把这些逻辑控制流画成时序流程图,它们在时间线上是可以重叠的。

  并行是指程序的运行状态。如果一个程序在某一时刻被多个CPU流水线同时进行处理,那么我们就说这个程序是以并行的形式在运行。(严格意义上讲,我们不能说某程序是“并行”的,因为“并行”不是描述程序本身,而是描述程序的运行状态,但这篇小文里就不那么咬文嚼字,以下说到“并行”的时候,就是指代“以并行的形式运行”)显然,并行一定是需要硬件支持的。

  而且不难理解:

    1. 并发是并行的必要条件,如果一个程序本身就不是并发的,也就是只有一个逻辑控制流,那么我们不可能让其被并行处理。
    1. 并发不是并行的充分条件,一个并发的程序,如果只被一个CPU流水线进行处理(通过分时),那么它就不是并行的。

为什么协程比线程轻量?

    1. go协程调用跟切换比线程效率高

线程并发执行流程:
  线程是内核对外提供的服务,应用程序可以通过系统调用让内核启动线程,由内核来负责线程调度和切换。线程在等待IO操作时线程变为unrunnable状态会触发上下文切换。现代操作系统一般都采用抢占式调度,上下文切换一般发生在时钟中断和系统调用返回前,调度器计算当前线程的时间片,如果需要切换就从运行队列中选出一个目标线程,保存当前线程的环境,并且恢复目标线程的运行环境,最典型的就是切换ESP指向目标线程内核堆栈,将EIP指向目标线程上次被调度出时的指令地址。

go协程并发执行流程:
  不依赖操作系统和其提供的线程,golang自己实现的CSP并发模型实现:M, P, G
  go协程也叫用户态线程,协程之间的切换发生在用户态。在用户态没有时钟中断,系统调用等机制,因此效率高

  • 2.go协程占用内存少

  执行go协程只需要极少的栈内存(大概是4~5KB),默认情况下,线程栈的大小为1MB。
  goroutine就是一段代码,一个函数入口,以及在堆上为其分配的一个堆栈。所以它非常廉价,我们可以很轻松的创建上万个goroutine,但它们并不是被操作系统所调度执行。

参考资料

相关文章

  • 程序员的自我修养 IO/CUP密集型线程

      有关进程线程协程的概念在上一篇文章 golang协程为什么比线程轻量https://www.jianshu.c...

  • golang协程为什么比线程轻量?

    先理解下进程、线程跟协程的概念: 进程   计算机的操作系统模式是一种多任务系统,操作系统接管了所有的硬件资源,并...

  • [Android] 深入理解Kotlin协程

    Kotlin协程 协程由程序自己创建和调度,不需要操作系统调度,所以协程比线程更加轻量。相比于线程的切换,协程切换...

  • Python 中的协程(coroutine)简介

    Python 中的协程(Coroutine)是一种比线程(Thread)更加轻量的代码执行机构。与线程不同的是,协...

  • 简易协程-1

    什么是协程 协程是轻量级的线程,轻量的意思就是占用内存少,一个线程可以轻松的跑出数万以上的协程。协程的执行是并发的...

  • Go语言学习笔记七(并发编程)

    协程机制 Golang 线程和协程的区别 备注:需要区分进程、线程(内核级线程)、协程(用户级线程)三个概念。 进...

  • 协程

    协程 1. 协程介绍 协程又称微线程,从名字可以看出,协程的粒度比线程更小,并且是用户管理和控制的,多个协程可以运...

  • 什么是协程

    协程是比线程更小的一种执行单元,你可以认为是轻量级的线程,之所以说轻,其中一方面的原因是协程所持有的栈比线程要小很...

  • Python3学习笔记_part_C

    协程 协程,又称微线程,纤程。英文名Coroutine。 协程其实可以认为是比线程更小的执行单元。 为啥说他是一个...

  • 从 generator 到 async/await

    协程 协程是一种比线程更加轻量级的存在。可以把协程看成是跑在线程上的任务,一个线程上可以存在多个协程,但是在线程上...

网友评论

    本文标题:golang协程为什么比线程轻量?

    本文链接:https://www.haomeiwen.com/subject/kpibhctx.html