【Go并发编程】第一篇 - Goroutines调度

送外卖
• 阅读 6888

【Go并发编程】第一篇 - Goroutines调度

进程和线程

当运行一个应用程序的时候,操作系统会给这个应用程序启动一个进程。我们可以将进程看作一个包含应用程序在运行中需要用到和维护的各种资源的容器。一个进程至少包含一个线程,这个线程就是主线程。操作系统会调度线程到不同的CPU上执行,这个CPU不一定就是进程所在的CPU。
【Go并发编程】第一篇 - Goroutines调度

  • 进程:资源的所有权
  • 线程:执行和调度的基本单位
  • 同一进程下的各个线程共享资源,但寄存器、栈、PC不共享

Go调度

基本术语

【Go并发编程】第一篇 - Goroutines调度

Go Runtime管理调度,垃圾收集和Goroutine的运行时环境。这里我们只谈调度器。

Runtime调度器通过把Goroutine绑定到操作系统线程来运行它们。Goroutine可以看作是轻量级的线程。每个Goroutine用G来表示,它包含了用来跟踪栈的字段和当前状态。

Runtime跟踪每一个G并且把它们绑定到P(Logical Processor)。P可以被看作抽象资源或者上下文,操作系统线程用M来表示(OS Thread)需要获取它以便来执行G。你可以通过runtime.GOMAXPROCS(numLogicalProcessors)来调整P(Logical Processors)。

G-P-M调度模型

Go 1.1中实现了G-P-M调度模型和work stealing算法,这个模型一直沿用至今:
【Go并发编程】第一篇 - Goroutines调度

每一个G(Goroutine)需要绑定到P(Logical Processor)才能调度执行;就像每一个User-level Thread绑定到Kernel Thread才能被调度执行。

M、P 和 G 之间的交互

【Go并发编程】第一篇 - Goroutines调度

创建一个Goroutine并准备运行,这个Goroutine会被放到调度器的Global队列中。然后调度器就将这些队列中的Goroutine分配给一个P(Logical Processor),并放到这个P对应的Local队列中。Local队列中的Goroutine会一直等待直到自己被分配的P执行。

如果正在运行的Goroutine被一个系统调用阻塞,如打开一个文件。当这种情况发生时,M2(OS Thread)和Goroutine会从P0(Logical Processor)上分离,这个M2会一直阻塞直到系统调用返回(见上图右边)。与此同时,这个P0就失去了用来运行的M2。所以,调度器会创建一个新的M3,并将其绑定到该P0上。之后,调度器会从Local队列中选择另外一个Goroutine运行。一旦刚才阻塞的系统调用执行完毕并返回,对应的Goroutine会放回到Local队列。

并发(Concurrency)不是并行(Parallelism)

【Go并发编程】第一篇 - Goroutines调度

上图解释了并发和并行的区别
并发 - 一个咖啡机同时服务两个队列
并行 - 两个咖啡机服务同时服务两个队列

【Go并发编程】第一篇 - Goroutines调度

如果希望让Goroutine并行,必须使用多于一个P(Logical Processor)。当有多个P时,调度器会将Goroutine平等分配到每个P上。这会让Goroutine在不同M(OS Thread)上运行。不过要想真的实现并行的效果,用户需要让自己的程序运行在有多个物理处理器的机器上。

参考资料。
  1. Go In Action
  2. 也谈goroutine调度器
  3. Go scheduler: Ms, Ps & Gs
点赞
收藏
评论区
推荐文章
半臻 半臻
4年前
Python基础10——线程、进程、协程
18线程18.1进程和线程进程:打开一个程序至少就会有一个进程。操作系统进行资源分配的基本单位线程:线程是CPU调度的基本单位,每个进程至少都有一个线程。单线程:只有一个线程pythondeffuna():print(123)deffunb():print(456)funa()funb()先执行funa再执行funb多线程线程
Wesley13 Wesley13
3年前
java多线程总结
线程或者说多线程,是我们处理多任务的强大工具。线程和进程是不同的,每个进程都是一个独立运行的程序,拥有自己的变量,且不同进程间的变量不能共享;而线程是运行在进程内部的,每个正在运行的进程至少有一个线程,而且不同的线程之间可以在进程范围内共享数据。也就是说进程有自己独立的存储空间,而线程是和它所属的进程内的其他线程共享一个存储空间。线程的使用可以使我们能够并行
DevOpSec DevOpSec
4年前
python多线程原理和详解(一)
python多线程原理和详解线程概念1.线程是什么?线程也叫轻量级进程,是操作系统能够进行运算调度的最小单位,它被包涵在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其他线程共享进程所拥有的全部资源。一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。
Wesley13 Wesley13
3年前
java多线程大汇总,线程与进程,线程调度,并发与并行,创建线程方式,线程生命周期,线程安全,线程通信,线程池
1.线程与进程进程是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间线程1、是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行.一个进程最少有一个线程2、线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分成若干个线程
限时发布!非科班程序员金三银四求职经历
进程和线程的概念进程是具有独立功能的程序在一个数据集合上运行的过程。进程是系统进行资源分配的单位,实现的操作系统的并发。线程是比进程更小的能独立运行的单位,是  调度的基本单位,实现了进程内部的并发。线程成为了程序执行流的最小单位。进程状态转换图1.创建状态:进程正在被创建。2.就绪状态:进程已经分配到了除  之外的所有资源,只要分配到  就可以开
Wesley13 Wesley13
3年前
Java并发基础
一、多线程基础知识1.进程和线程进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。线程:进程内部的一个独立执行单元;一个进程可以同时并发的运行多个线程,
Wesley13 Wesley13
3年前
Java面试官都爱问的多线程和并发面试题汇总,多刷一题,多份安心!
Java多线程面试问题1、进程和线程之间有什么不同?一个进程是一个独立(selfcontained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不同的类和程序的单一进程。线程可以被称为轻量级进程。线程需要较少的资源来创建和驻留在进
Stella981 Stella981
3年前
Python 浅析线程(threading模块)和进程(process)
    线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务进程与线程什么是线程(threading)?Athreadisanexecutioncontext,whichisall
Stella981 Stella981
3年前
Python process (进程)
进程(process)进程是对各种资源管理的集合,包含对各种资源的调用、内存的管理、网络接口的调用进程要操作CPU必须先启动一个线程,启动一个进程的时候会自动创建一个线程,进程里的第一个线程就是主线程程序执行的实例有唯一的进程标识符(pid)multiprossing模块
Wesley13 Wesley13
3年前
Java中多线程并发体系知识点汇总
一、多线程1、操作系统有两个容易混淆的概念,进程和线程。进程:一个计算机程序的运行实例,包含了需要执行的指令;有自己的独立地址空间,包含程序内容和数据;不同进程的地址空间是互相隔离的;进程拥有各种资源和状态信息,包括打开的文件、子进程和信号处理。线程:表示程序的执行流程,是CPU调度执行的基本单位;线程有自己的程序计数器、寄存器、堆栈和帧。同一进
深入浅出线程池 | 京东云技术团队
一、线程1、什么是线程线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。2、如何创建线程2.1、JAVA中