当前位置: 首页 > news >正文

43-Golang中的goroutine!!!

Golang中的goroutine

    • 进程和线程说明
    • 并发和并行
      • 并发
      • 并行
    • Go协程和Go主线程
      • 案例
      • 小结
    • goroutine的调度机制
      • MPG模式基本介绍
        • MPG模式运行的状态1
        • MPG模式运行的状态2
      • 设置GOlang运行的CPU数
    • 不同 goroutine之间如何通讯
      • 使用全局变量加锁同步改进程序

进程和线程说明

  • 1.进程就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位
  • 2.线程是进程的一个执行实例,是程序执行的最小单元,它是比进程更小的能独立运行的基本单位
  • 3.一个进程可以创建和销毁多个线程,同一个进程中的多个线程可以并发执行
  • 4.一个程序知道有一个进程,一个进程至少有一个线程

并发和并行

1、多线程程序在单核上运行,就是并发

2、多线程程序在多核上运行,就是并行

并发

因为是在CPU上,比如都有10个线程,每个线程执行10毫秒(进行轮询操作),从人的角度看,好像这10个线程都在运行,但是从微观上看,在某一个时间点看,其实只有一个线程在执行,这就是并发

并行

因为是在多个CPU上(比如有10个CPU),比如有10个线程,每个线程执行10毫秒(各自在不同的CPU上执行),从人的角度看,这10个线程都在运行,并且从微观上看,在某一个时间点看,也同时有10个线程在执行,这就是并行
在这里插入图片描述

Go协程和Go主线程

1.Go主线程(有程序员直接称为线程/也可以理解成进程):一个Go线程上,可以起多个协程,可以理解为协程是轻量级的线程

2.Go协程的特点

  • 有独立的栈空间
  • 共享程序堆空间
  • 调度由用户控制
  • 协程是轻量级的线程
    在这里插入图片描述

案例

编写一个程序

1、在主线程中(也可以理解成进程)中,开启一个goroutine,改协程每隔1秒输出“hello,world”

2、在主线程中也每隔1秒“hello,golang”,输出10次后,退出程序

3、要求主线程和goroutine同时执行

4、画出主线程和协程执行流程图

package mainimport ("fmt""strconv""time"
)func test() {for i := 1; i <= 10; i++ {fmt.Println("test () hello,world" + strconv.Itoa(i))time.Sleep(time.Second)}
}func main() {go test() //开启了一个协程for i := 0; i <= 10; i++ {fmt.Println("main() hello,golang" + strconv.Itoa(i))time.Sleep(time.Second)}
}
/*
main() hello,golang0
test () hello,world1
test () hello,world2
main() hello,golang1
main() hello,golang2
test () hello,world3
test () hello,world4
main() hello,golang3
main() hello,golang4
test () hello,world5
test () hello,world6
main() hello,golang5
main() hello,golang6
test () hello,world7
test () hello,world8
main() hello,golang7
main() hello,golang8
test () hello,world9
main() hello,golang9
test () hello,world10
main() hello,golang10*/

在这里插入图片描述

小结

  • 1、主线程是一个物理线程,直接作用在CPU上的。是重量级的,非常消耗CPU资源
  • 2、协程从主线程开启的,是轻量级的线程,是逻辑态。对资源消耗相对小
  • 3、Golang的协程机制时重要的特点,可以轻松的开启上万个协程。其他编程语言的并发机制时一般基于线程的,开启过多的线程,资源耗费大,这里就突显Golang在并发上的优势了

goroutine的调度机制

MPG模式基本介绍

在这里插入图片描述

MPG模式运行的状态1

  • 1、当前程序有三个M,如果三个M都在一个CPU运行,就是并发,如果在不同的CPU运行就会并行
  • 2、M1,M2,M3正在执行一个G,M1的协程队列有三个,M2的协程队列有三个,M3的协程队列有两个
  • 3、从下图可以看到:Go的协程是轻量级的线程,是逻辑态的,Go可以容易的起上万个协程
  • 4、其他程序c/java的多线程,往往是内核态的,比较重量级,几千个线程可能耗光CPU

在这里插入图片描述

MPG模式运行的状态2

  • 1、分两部分来看
  • 2、原来的情况是M0主线程正在执行Go协程,另外有三个协程在队列等待
  • 3、如果Go协程阻塞,比如读取文件或者数据库等
  • 4、这时就会创建M1主线程(也可能是从已有的线程池中取出M1),并且将等待的3个协程挂到M1下开始执行,M0的主线程下的Go任然执行文件io的读写
  • 5、这样的MPG调度模式,可以既让GO执行,同时不会让队列的其他协程一直阻塞,任然可以并发/并行执行
  • 6、等到GO不阻塞了,M0会被放到空闲的主线程继续执行(从已有的线程池中取),同时GO又会被唤醒

在这里插入图片描述

设置GOlang运行的CPU数

介绍:为了充分利用多CPU的优势,在golang中,设置运行的CPU数目

1.go1.8后默认让程序运行在多个核上,可以不用设置了

2.go1.8前,要设置以下,可以更高效的利用CPU

package mainimport ("fmt""runtime"
)func main() {//获取当前系统CPU数量num := runtime.NumCPU()//这里设置num-1的CPU运行go程序runtime.GOMAXPROCS(num)fmt.Println("num=", num)
}
//num=8

不同 goroutine之间如何通讯

1、全局变量加锁同步

2、channel

使用全局变量加锁同步改进程序

  • 因为没有对全局变量m加锁,因此会出现资源争夺问题,代码会出现错误,提升concurrent map writes
  • 解决方案:加入互斥锁
  • 数的阶乘很大,结果会越界,可以将求阶乘改成sum += uint64(i)
    在这里插入图片描述
    在这里插入图片描述
http://www.lryc.cn/news/36283.html

相关文章:

  • [深入理解SSD系列 闪存实战2.1.5] NAND FLASH基本读操作及原理_NAND FLASH Read Operation源码实现
  • pandas库中的read_csv函数读取数据时候的路径问题详解(ValueError: embedded null character)
  • 【量化交易笔记】4.移动平均值的实现
  • 2023年3月份的野兔在线工具系统版本更新
  • 科技成果赋智中小企业深度行 边界无限靖云甲ADR入选十大优秀案例
  • 我们的理性何处安放
  • RecyclerView的详细使用
  • 一、向量及其线性运算
  • Spring Cloud/Spring Cloud Alibaba核心知识总结
  • Locust框架从0到1入门
  • C++:整数(short ,int,long,long long)表示范围
  • 会声会影2023旗舰版新功能介绍,Corel VideoStudio Ultimate2023以及电脑系统配置要求
  • 软件测试用例篇(5)
  • 三个修饰符
  • JVM调优面试题——参数命令专题
  • 单例模式(设计模式详解)
  • 设计一份关于文化遗产视频的调查问卷
  • Linux内核移植
  • 忆享科技优化入职培训加强人效管理全面迎接新挑战
  • Spring——注解开发依赖注入和管理第三方bean
  • shell可能考你但是不常用的基础($篇)
  • 项目管理必备:如何绘制一份优秀的甘特图?
  • 【点云学习】多时相激光雷达点云
  • 使用QT C++编写一个随机生成网络ip地址的程序
  • Web前端学习:章三 -- JavaScript预热(三)
  • java实用小技巧:判断list是否有重复项
  • SQL优化常用招数(上)
  • C++并发之探索编程三
  • 某智能驾驶企业:CACTER云网关为O365系统护航
  • 网络安全与信息安全的主要区别讲解-行云管家