【Golang 面试 - 进阶题】每日 3 题(十)

✍个人博客:Pandaconda-CSDN博客

📣专栏地址:http://t.csdnimg.cn/UWz06

📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~

❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

28. Go 线程实现模型?

Go 实现的是两级线程模型(M:N),准确的说是 GMP 模型,是对两级线程模型的改进实现,使它能够更加灵活地进行线程之间的调度。

背景

|----------|---------------------------------|-----------------------------------|
| | 含义 | 缺点 |
| 单进程时代 | 每个程序就是一个进程,直到一个程序运行完,才能进行下一个进程 | 1. 无法并发,只能串行 2. 进程阻塞所带来的 CPU 时间浪费 |
| 多进程/线程时代 | 一个线程阻塞, CPU 可以立刻切换到其他线程中去执行 | 1. 进程/线程占用内存高 2. 进程/线程上下文切换成本高 |
| 协程时代 | 协程(用户态线程)绑定线程(内核态线程),CPU 调度线程执行 | 1. 实现起来较复杂,协程和线程的绑定依赖调度器算法 |

线程 -> CPU 由操作系统调度,协程 -> 线程由 Go 调度器来调度,协程与线程的映射关系有三种线程模型。

三种线程模型

线程实现模型主要分为:内核级线程模型用户级线程模型两级线程模型,他们的区别在于用户线程与内核线程之间的对应关系。

1. 内核级线程模型(1:1)

1 个用户线程对应 1 个内核线程,这种最容易实现,协程的调度都由 CPU 完成了。

优点:

  • 实现起来最简单

  • 能够利用多核

  • 如果进程中的一个线程被阻塞,不会阻塞其他线程,是能够切换同一进程内的其他线程继续执行

缺点:

  • 上下文切换成本高,创建、删除和切换都由 CPU 完成

2. 用 户级线程模型(N:1)

1 个进程中的所有线程对应 1 个内核线程。

优点:

  • 上下文切换成本低,在用户态即可完成协程切换

缺点:

  • 无法利用多核

  • 一旦协程阻塞,造成线程阻塞,本线程的其它协程无法执行

3. 两 级线程模型(M:N)

M 个线程对应 N 个内核线程。

优点:

  • 能够利用多核

  • 上下文切换成本低

  • 如果进程中的一个线程被阻塞,不会阻塞其他线程,是能够切换同一进程内的其他线程继续执行

缺点:

  • 实现起来最复杂

29. G MP 指的是什么?

GMP 指的是 Go 语言运行时的三个关键组件:Goroutine、M(Machine)和 P(Processor)。

Goroutine 已经在前面的问题中讲到了,是 Go 语言中轻量级线程的实现,它可以在单个进程中同时执行多个任务,实现了并发编程。

M(Machine)是 Go 语言运行时的机器模型,它是操作系统线程(OS thread)和 Goroutine 之间的中间件。在 Go 语言中,每个 Goroutine 都会被分配到一个 M 上执行,而每个 M 只能同时执行一个 Goroutine,这是 Go 语言实现并发的关键之一。当一个 Goroutine 阻塞或者需要等待 I/O 操作时,对应的 M 会被回收,等待其它 Goroutine 上的任务。

P(Processor)是 Go 语言运行时的处理器,它负责调度 Goroutine 在 M 上运行,同时也负责管理 Goroutine 的队列、调度等工作。在 Go 语言中,P 的数量是可以配置的,默认情况下为机器的核心数,但是可以通过环境变量 GOMAXPROCS 来进行修改。

GMP 模型在 Go 语言中实现了一种高效的并发编程机制,它可以轻松地创建数以千计的 Goroutine,实现并发编程,而不会导致系统资源的耗尽。同时,GMP 模型也提供了一个高度灵活的调度器,可以自动地调整 Goroutine 的数量和 P 的数量,以适应不同的负载。

30. 1 .0 之前 GM 调度模型

在 Go 1.0 之前,Go 语言的运行时使用的是 GM 调度模型,与现在的 GMP 调度模型有所不同。在 GM 模型中,M(Machine)和 P(Processor)被合并为一个单一的调度器,称为 G(Goroutine)调度器。

在 GM 模型中,所有的 Goroutine 都被分配到一个全局的 Goroutine 队列中,每个 M 都会从队列中取出一个 Goroutine 来执行。当一个 Goroutine 阻塞或者需要等待 I/O 操作时,对应的 M 会回收它,并从全局队列中取出另外一个 Goroutine 继续执行。这样,一个 M 可以执行多个 Goroutine,而不像现在的 GMP 模型一样只能执行一个。

GM 模型相对于 GMP 模型的优势是它的调度器更加简单,同时在低负载的情况下可以更加高效地利用系统资源。然而,GM 模型也存在一些问题,最大的问题是在高负载的情况下,由于所有的 Goroutine 都被放在全局队列中,导致竞争变得非常激烈,从而降低了并发性能。另外,GM 模型也无法支持多核 CPU 的并行执行,因为它只有一个单一的调度器。

因此,从 Go 1.0 开始,Go 语言的运行时采用了 GMP 调度模型,通过引入 M 和 P 的概念,实现了更加高效的并发编程机制,同时支持多核 CPU 的并行执行。

相关推荐
Qter_Sean14 分钟前
自己动手写Qt Creator插件
开发语言·qt
何曾参静谧18 分钟前
「QT」文件类 之 QIODevice 输入输出设备类
开发语言·qt
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
码上一元2 小时前
SpringBoot自动装配原理解析
java·spring boot·后端
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
冰芒猓4 小时前
SpringMVC数据校验、数据格式化处理、国际化设置
开发语言·maven
失落的香蕉4 小时前
C语言串讲-2之指针和结构体
java·c语言·开发语言
jerry6094 小时前
7天用Go从零实现分布式缓存GeeCache(改进)(未完待续)
分布式·缓存·golang
枫叶_v4 小时前
【SpringBoot】22 Txt、Csv文件的读取和写入
java·spring boot·后端
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习