一、go协程与go主线程
Go主线程:一个Go线程上,可以起多个协程,协程是轻量级的线程。
二、go协程特点
1、有独立的栈空间
2、共享程序堆空间
3、调度由用户控制
4、协程是轻量级的线程
三、入门练习
package main
import (
"fmt"
"time"
)
func test() {
for i := 0;i <10 ;i++ {
fmt.Println("协程:hello world",i)
time.Sleep(time.Second)
}
}
func main() {
//开启协程
go test()
for i := 0;i <10 ;i++ {
fmt.Println("主线程程:hello world",i)
time.Sleep(time.Second)
}
}
四、go协程流程图
五、MPG模式
1、M:操作系统的主线程(是物理线程)
2、P:协程执行需要的上下文
3、G:协程
六、设置cpu数
package main
import (
"fmt"
"runtime"
)
func main() {
//查看本机cpu个数
cpu := runtime.NumCPU()
fmt.Println(cpu)
//设置要使用的cpu个数
runtime.GOMAXPROCS(cpu-1)
}
七、资源竞争问题
使用全局变量加锁来解决
package main
import (
"fmt"
"sync"
"time"
)
var Map = make(map[int]int,10)
//声明全局互斥锁
var look = sync.Mutex{}
//计算阶乘
func test1(n int) {
num := 1
for i:=1;i <= n ;i++ {
num *= i
}
//加锁
look.Lock()
Map[n] = num
//解锁
look.Unlock()
}
func main() {
//开启协程
for i:=1;i <= 20 ;i++ {
go test1(i)
}
//休眠
time.Sleep(time.Second * 10)
look.Lock()
for key, value := range Map {
fmt.Println(key,value)
}
look.Unlock()
}