从进程、线程过渡:理解协程


进程

进程是一个程序在一个数据集中的一次动态执行过程,可以理解为“正在执行的程序”。进程一般由程序集、数据集、进程控制块三部分组成。进程是系统进行资源分配和调度的基本单位,是操作系统的基础。进程是线程的容器,进程是程序的实体。

  • 程序集:描述进程要完成哪些功能以及如何完成
  • 数据集:程序在执行过程所需要使用的资源
  • 进程控制块:保存程序运行的状态
  • 进程的局限性是创建、撤销和切换的开销比较大。

线程

线程也叫轻量级进程,它是一个基本的CPU执行单元,也是程序执行的最小单位。一个进程最少有一个主线程。

  • 线程的优点:减小了程序并发执行的开销,提高了系统的并发性能。
  • 线程的缺点:线程没有自己的系统资源,只有运行时不可缺少的资源,但是同一进程的各线程可以共享进程所拥有的系统资源。对于某些独占资源存在锁机制,处理不当会出现死锁。

协程

协程是一种用户态的轻量级线程,又称微线程。协程的调度完全由用户控制(进程和线程都是由cpu 内核进行调度)。

  • 协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

  • 对于 进程、线程,都是有内核进行调度,有 CPU 时间片的概念,进行 抢占式调度(有多种调度算法)
    对于 协程(用户级线程),这是对内核透明的,也就是系统并不知道有协程的存在,是完全由用户自己的程序进行调度的,因为是由用户程序自己控制,那么就很难像抢占式调度那样做到强制的 CPU 控制权切换到其他进程/线程,通常只能进行 协作式调度,需要协程自己主动把控制权转让出去之后,其他协程才能被执行到。

  • 协程的优点:

  1. 协程执行效率高。因为子程序切换不是线程切换,由程序自身控制,没有线程切换的开销。
  2. 协程不需要多线程的锁机制。在协程中控制共享资源不加锁,只需要判断状态就好

goroutine协程 区别
本质上,goroutine 就是协程。 不同的是,Golang 在 runtime、系统调用等多方面对 goroutine 调度进行了封装和处理,当遇到长时间执行或者进行系统调用时,会主动把当前 goroutine 的CPU § 转让出去,让其他 goroutine 能被调度并执行,也就是 Golang 从语言层面支持了协程。

Golang 的一大特色就是从语言层面原生支持协程,在函数或者方法前面加 go关键字就可创建一个协程。

协程与线程的比较

每个 goroutine (协程) 默认占用内存远比 Java 、C 的线程少。
goroutine:2KB(官方)
线程:8MB(参考网络)= 8192K

线程/goroutine 切换开销方面:goroutine 远比线程小!

  • 线程:涉及模式切换(从用户态切换到内核态)、16个寄存器、PC、SP…等寄存器的刷新等。
  • goroutine:只有三个寄存器的值修改 - PC / SP / DX.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章