golang分析--goroutine,进程,线程

概念总览

概述

定义 通讯方式
进程 一个运行中的程序,资源分配的最小单位 管道、信号、共享内存/信号量/消息队列
线程 轻量级进程,操作系统调度(cpu调度)执行的最小单位 互斥锁、条件变量、posix匿名信号量
协程 轻量级的线程 全局变量和锁同步,Channel管道进行数据同步

三者联系及区别

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200112104425395.png在这里插入图片描述
联系
一个程序至少要有一个进程,一个进程至少要有一个线程,进程本身不运行是线程的容器,多线程就像火车上的每节车厢,进程就是火车,协程则是一种轻量级的线程,协程调度完全由用户控制,而进程线程都由cpu内核调度。
区别
1.切换开销更小
这是goroutine于线程的主要区别,也是golang能够实现高并发的主要原因。线程的调度方式是抢占式的,如果一个线程的执行时间超过了分配给它的时间片,就会被其它可执行的线程抢占。在线程切换的过程中需要保存/恢复所有的寄存器信息,比如16个通用寄存器,PC(Program Counter),SP(Stack Pointer),段寄存器等等。
而goroutine的调度是协同式的,它不会直接地与操作系统内核打交道。当goroutine进行切换的时候,之后很少量的寄存器需要保存和恢复(PC和SP)。因此gouroutine的切换效率更高。
2.每个goroutine默认内存比java,c少,goroutine2kb,线程8MB.
3.由于线程创建时需要向操作系统申请资源,并且在销毁时将资源归还,因此它的创建和销毁的开销比较大。相比之下,goroutine的创建和销毁是由go语言在运行时自己管理的,因此开销更低。

Goroutine的调度

协同式goroutine的切换点:
1.Channel接受或者发送会造成阻塞的消息
2.当一个新的goroutine被创建时
3.可以造成阻塞的系统调用,如文件和网络操作
4.垃圾回收
调度器工作方式:
M指的是OSThread,一个M直接关联了一个内核线程。由操作系统管理。
P指的是”processor”,代表了M所需的上下文环境,也是处理用户级代码逻辑的处理器。它负责衔接M和G的调度上下文,将等待执行的G与M对接。(上下文P(Processor)的数量在启动时设置为GOMAXPROCS环境变量的值或通过运行时函数GOMAXPROCS()。)
G指的是Goroutine,其实本质上也是一种轻量级的线程。包括了调用栈,重要的调度信息,例如channel等。

支撑整个调度器的主要有4个重要结构,分别是M、G、P、Sched:
M代表内核级线程,一个M就是一个线程,goroutine就是跑在M之上的;M是一个很大的结构,里面维护小对象内存cache(mcache)、当前执行的goroutine、随机数发生器等等非常多的信息。
P全称是Processor,处理器,它的主要用途就是用来执行goroutine的,所以它也维护了一个goroutine队列,里面存储了所有需要它来执行的goroutine,这个P的角色可能有一点让人迷惑,一开始容易和M冲突,后面重点聊一下它们的关系。
G就是goroutine实现的核心结构了,G维护了goroutine需要的栈、程序计数器以及它所在的M等信息。
Sched结构就是调度器,它维护有存储M和G的队列以及调度器的一些状态信息等。

参考文档:
https://segmentfault.com/a/1190000019220859?utm_source=tag-newest
https://blog.csdn.net/daaikuaichuan/article/details/82951084
https://baijiahao.baidu.com/s?id=1620972759226100794&wfr=spider&for=pc

发布了212 篇原创文章 · 获赞 33 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/hello_bravo_/article/details/103943542