这是我参与「 第五届青训营 」伴学笔记创作活动的第 2 天 整理了goroutine相关的知识内容,以及操作系统基础知识的回顾
操作系统知识回顾
进程与线程
- 进程就是程序程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。
- 线程是进程的一个执行实例,是程序执行的最小单元,它是比进程更小的能独立运行的基本单位。
- 一个进程可以创建和销毁多个线程,同一个进程中的多个线程可以并发执行。
- 一个程序至少有一个进程,一个进程至少有一个线程。
并发、并行、串行
- 串行任务依次执行,第一个任务执行完才会执行第二个
- 并行所有任务同步执行且互不干扰
- 并发任务交替执行但只有一个任务在运行,允许互相干扰
goroutine
- Go主线程(有程序员直接称为线程/也可以理解成进程):一个Go线程上,可以起 多个协程,你可以这样理解,协程是轻量级的线程。
- Go协程的特点:有独立的栈空间,共享程序堆空间,调度由用户控制,协程是轻量级的线程
goroutine实例
helloword实例
func test() {
for i := 1; i <= 10; i++ {
fmt.Println("goroutine", i)
time.Sleep(time.Second)
}
}
func main() {
go test() // 开启协程
for i := 1; i <= 10; i++ {
fmt.Println("main", i)
time.Sleep(time.Second)
}
}
main 1 goroutine 1 goroutine 2 main 2 main 3 goroutine 3 main 4 goroutine 4 goroutine 5 main 5 main 6 goroutine 6 goroutine 7 main 7 main 8 goroutine 8 goroutine 9 main 9 main 10 goroutine 10
阶乘实例
var (
myMap = make(map[int]int, 10)
lock sync.Mutex // 互斥锁
)
func test(n int) {
res := 1
for i := 1; i <= n; i++ {
res *= i
}
lock.Lock()
myMap[n] = res
lock.Unlock()
}
func main() {
for i := 1; i <= 20; i++ {
go test(i)
}
lock.Lock()
for i, v := range myMap {
fmt.Printf("map[%d]=%d\n", i, v)
}
lock.Unlock()
}
goroutine MPG调度模式
- M:操作系统的主线程(是物理线程)
- P:协程执行需要的上下文
- G:协程
当前程序有三个M,如果三个M都在一个cpu运行,就是并发,如果在不同的cpu运行就是并行M1,M2,M3.正在执行一个G,M1的协程队列有三个,M2的协程队列有3个,M3 协程队列有2个从上图可以看到: Go的协程是轻量级的线程,是逻辑态的,Go可以容易的起上万个协程其它程序c/java的多线程,往往是内核态的,比较重量级,几千个线程可能耗光cpu