Go学习笔记 -- 并发原理
admin
2024-04-01 14:34:12
0

文章目录

    • Go 协程和普通线程对比
      • 内核级线程(线程)
        • 线程优点
        • 线程缺点
      • 用户级线程(协程)
        • 协程优点
        • 协程缺点
    • 调度器(GPM)
      • G\P\M 之间的工作关系
    • Go 使用协程
      • 创建协程
      • 注意

Go 协程和普通线程对比

       Go 拥有极强的并发编程能力,而 Go 并发编程强势原因,一部分原因是因为语法简单 ,还有一个更核心的原因是 Go 中协程 goroutine (用户态线程)的存在。
       在 Gogoroutine 是比普通线程(内核态线程)更加轻量化的存在。

内核级线程(线程)

       内核态线程简称线程,是在内核中维护了线程表进行跟踪监控的线程。是 CPU 调度和分派的基本单位,是具备进程某些属性,能够独立运行的更小单位,所以也称为轻量级进程。

       如果使用内核态线程在一个 CPU 上实现任务的并发,那么 CPU 会通过分配时间片的方式去执行任务,当正在运行的任务所分配的时间片用完了,就会切换到另一个任务,而在切换的之前会保存当前任务的状态(CPU寄存器、程序计数器中的内容),当下次再次切换到这个任务之前就会先加载之前保存到任务状态,这个过程称作上下文切换。

       而在上下文切换的过程该线程会从用户态转为内核态,加载时再由内核态转为用户态。而用户态和内核态切换的代价是很高的,从用户态到内核态的切换比较耗费资源的,而且内核资源是很珍贵的,所以内核态线程过多时,可能会出现内核资源耗尽的情况。

线程优点

  1. 多核 CPU 利用 :内核具有0级权限,因此可以在多个 CPU 上执行内核线程
  2. 操作系统级优化:线程之间是相对独立的,一个线程阻塞不会影响其他线程的执行。内核态线程在进行你 IO 操作时不需要进行系统调用 。

线程缺点

  1. 创建的时候需要切换到内核态,所以创建成本比较高。
  2. 切换的时候,需要用户态和内核态之间频繁的切换,切换成本较高。
  3. 线程数量有限制,当内核态线程过多时,会出现内核资源耗尽的情况。

用户级线程(协程)

       用户态线程简称协程,是完全由用户控制的线程,内核并不会感知到它的存在,用户级线程的创建、销毁、调度、状态变更以及其中的代码和数据都完全需要我们的程序自己去实现和处理。因为是存在在用户空间上的线程,所以在切换时不存在用户态和内核态的转换。

协程优点

  1. 不由内核管理,由用户自主管理,创建成本比较低。
  2. 不存在内核态和用户态的切换,切换成本比较低。
  3. 不需要操作系统去调度,所以可以跨操作系统,并且更加灵活、更容易控制。

协程缺点

  1. 因为操作系统的内核看不到协程,所以同属于一个进程的协程只能占有一个核,不能发挥多核优势。
  2. 操作系统不能主动调度协程,所以后面的协程只能等待前面的写成执行完才能获取到 CPU 资源。
  3. 同上,当前协程阻塞会导致后面的写成无法执行。
  4. 内核协作成本高,当要进行一些高权限的操作,比如读写文件时,需要频繁地进行用户态和内核态的切换。

调度器(GPM)

       GPMGo 语言运行时系统的重要组成部分
       其中 G 代表 goroutine 即协程,M 代表 machine 即系统线程、P 代表 Proccessor 代表写成和线程之间的联系

简单点理解就是:

G 是要被执行的任务实例
M 是实际的执行载体,需要绑定 P 成为一个执行单元才能调度 G
P 可以看作是任务处理器,P 中保存 M 执行 G 时的一些资源,P 决定了哪个 G 能配分配到哪个 M 上

G\P\M 之间的工作关系

       G 要调度到 M 上才能运行,M 需要关联 P 才可以执行 Go 代码,但当处理阻塞或系统调用中时,M 可以不用关联 P

       当进程启动时,会创建若干个(一般是内核数量)系统线程 M 和任务处理器 P,并一一绑定,因为一个线程对应一个 CPU 就不会出现上下文的切切换,能更大限度的节省资源。同时每一个任务处理器 P 都会对应一个私有的任务队列,但是私有队列有上限的,所以所有任务处理器还会有一个公用的全局队列。

       当有一个 G 被创建时,就会被放到一个任务处理器 P 的私有队列中等待被调度。如果所有的私有队列都满了,就会被放到全局队列中去。当 P 寻找 G 的时候,会先从自己的私有队列中寻找,如果没找到,再去全局队列中寻找,如果还是没有,它会去抢别的 P 中的 G。当任何地方都不能找到需要调度的 G 时,MP 则会断开连接。

       当 G 中进行了系统调用,则 M 也会进入系统调用状态,此时 P 会去寻找其他未在工作的 M 并为其寻找需要调度的任务。当 G 完成了系统调用,会进入空闲的私有队列或者全局队列,然后等待再次被调度。

       所以,GM 之间没有直接的联系,一个 G 可能被不同的 M 调度,一个 M 也可以调度不同的 G

Go 使用协程

创建协程

通过关键字 go 创建一个协程
一:普通函数创建

func goroutineTest(i int) {fmt.Println(i)
}
func main() {for i := 0; i < 10; i++ {go goroutineTest(i)}time.Sleep(time.Millisecond * 500)
}

二:匿名函数创建

func main() {for i := 0; i < 10; i++ {go func() {fmt.Println(i)}()}time.Sleep(time.Millisecond * 500)
}

三:匿名带参数函数创建

func main() {for i := 0; i < 10; i++ {go func(str string) {fmt.Println(str)}(fmt.Sprintf("%s%d", "s", i))}time.Sleep(time.Millisecond * 500)
}

注意

一:主协程不会等待子协程执行完毕
       以下列代码为例,一般来说控制台不会打印任何东西。原因是当代码运行到 go goroutineTest(i) 这一行时,并不是真正的会运行它,而是将它放到了任务队列中。所以可能子协程还没开始执行,主协程就已经退出了。所以我们可以再主协程加上等待。

func goroutineTest(i int) {fmt.Println(i)
}
func main() {for i := 0; i < 10; i++ {go goroutineTest(i)}time.Sleep(time.Millisecond * 500)
}

二:协程的执行没有顺序
       同上,当写成创建是,并不是立即执行,而是被分到不同的队列中等待被调度,而调度是不能保证先后顺序的(只能保证同一个队列中的任务先进先出),因此上述代码打印出来的结果大部分情况下时乱序的。
三:无参匿名函数中的变量变化

func main() {for i := 0; i < 3; i++ {go func() {fmt.Println(i)}()}time.Sleep(time.Millisecond * 500)
}

这段代码的打印结果如下:

2
2
3

       因为匿名函数不携带参数信息,只有匿名方法执行到 fmt.Println(i) 这一行时才会去读取 i 的值。又因为协程执行是有延迟的,所以当执行到这一句时, i 的值可能已经发生了变化。

下一篇再研究主协程等待子协程执行完毕以及确保子协程执行顺序的方法…

相关内容

热门资讯

电视安卓系统哪个品牌好,哪家品... 你有没有想过,家里的电视是不是该升级换代了呢?现在市面上电视品牌琳琅满目,各种操作系统也是让人眼花缭...
安卓会员管理系统怎么用,提升服... 你有没有想过,手机里那些你爱不释手的APP,背后其实有个强大的会员管理系统在默默支持呢?没错,就是那...
安卓系统软件使用技巧,解锁软件... 你有没有发现,用安卓手机的时候,总有一些小技巧能让你玩得更溜?别小看了这些小细节,它们可是能让你的手...
安卓系统提示音替换 你知道吗?手机里那个时不时响起的提示音,有时候真的能让人心情大好,有时候又让人抓狂不已。今天,就让我...
安卓开机不了系统更新 手机突然开不了机,系统更新还卡在那里,这可真是让人头疼的问题啊!你是不是也遇到了这种情况?别急,今天...
安卓系统中微信视频,安卓系统下... 你有没有发现,现在用手机聊天,视频通话简直成了标配!尤其是咱们安卓系统的小伙伴们,微信视频功能更是用...
安卓系统是服务器,服务器端的智... 你知道吗?在科技的世界里,安卓系统可是个超级明星呢!它不仅仅是个手机操作系统,竟然还能成为服务器的得...
pc电脑安卓系统下载软件,轻松... 你有没有想过,你的PC电脑上安装了安卓系统,是不是瞬间觉得世界都大不一样了呢?没错,就是那种“一机在...
电影院购票系统安卓,便捷观影新... 你有没有想过,在繁忙的生活中,一部好电影就像是一剂强心针,能瞬间让你放松心情?而我今天要和你分享的,...
安卓系统可以写程序? 你有没有想过,安卓系统竟然也能写程序呢?没错,你没听错!这个我们日常使用的智能手机操作系统,竟然有着...
安卓系统架构书籍推荐,权威书籍... 你有没有想过,想要深入了解安卓系统架构,却不知道从何下手?别急,今天我就要给你推荐几本超级实用的书籍...
安卓系统看到的炸弹,技术解析与... 安卓系统看到的炸弹——揭秘手机中的隐形威胁在数字化时代,智能手机已经成为我们生活中不可或缺的一部分。...
鸿蒙系统有安卓文件,畅享多平台... 你知道吗?最近在科技圈里,有个大新闻可是闹得沸沸扬扬的,那就是鸿蒙系统竟然有了安卓文件!是不是觉得有...
宝马安卓车机系统切换,驾驭未来... 你有没有发现,现在的汽车越来越智能了?尤其是那些豪华品牌,比如宝马,它们的内饰里那个大屏幕,简直就像...
p30退回安卓系统 你有没有听说最近P30的用户们都在忙活一件大事?没错,就是他们的手机要退回安卓系统啦!这可不是一个简...
oppoa57安卓原生系统,原... 你有没有发现,最近OPPO A57这款手机在安卓原生系统上的表现真是让人眼前一亮呢?今天,就让我带你...
安卓系统输入法联想,安卓系统输... 你有没有发现,手机上的输入法真的是个神奇的小助手呢?尤其是安卓系统的输入法,简直就是智能生活的点睛之...
怎么进入安卓刷机系统,安卓刷机... 亲爱的手机控们,你是否曾对安卓手机的刷机系统充满好奇?想要解锁手机潜能,体验全新的系统魅力?别急,今...
安卓系统程序有病毒 你知道吗?在这个数字化时代,手机已经成了我们生活中不可或缺的好伙伴。但是,你知道吗?即使是安卓系统,...
奥迪中控安卓系统下载,畅享智能... 你有没有发现,现在汽车的中控系统越来越智能了?尤其是奥迪这种豪华品牌,他们的中控系统简直就是科技与艺...