传统进程和线程概念介绍:



并发和并行概念介绍:


golang协程(goroutine)

golang协程的特点

  • 有独立的栈空间(栈可理解为数值类型,由堆中copy或引用到个体栈空间)
  • 共享程序堆空间(堆可理解为引用数据类型)
  • 调度由用户控制(线程启动和停止都可由用户控制,java则不行 )
  • 协程是轻量级的线程(理论上轻松可启上万条线程)


package main

import (
	"fmt"
	"strconv"
	"time"

)
func goroutine(){
	for i:=1;i<=10;i++{
		fmt.Println("hello world" + strconv.Itoa(i))
		time.Sleep(time.Second)
	}
}

func main(){
	// 开启一个协程
	go goroutine()

	for i:=1;i<=10;i++{
		fmt.Println("hello goroutine" + strconv.Itoa(i))
		time.Sleep(time.Second)
	}
}

PowerShell输出:

PS E:\...\src\gojson\jsondemo-10-24\goroutine> go run .\main.go     
hello world1
hello goroutine1
hello goroutine2
hello world2
hello world3
hello goroutine3
hello goroutine4
hello world4
hello world5
hello goroutine5
hello goroutine6
hello world6
hello world7
hello goroutine7
hello goroutine8
hello world8
hello world9
hello goroutine9
hello goroutine10
hello world10

go协程执行过程:

go协程总结:

  • go协程一般是以函数为单位的
  • 协程依托于主线程执行,主线程执行完毕或停止退出则协程也直接退出,即使没有执行完毕,若协程先于主线程执行完毕则主线程继续执行完毕
  • go协程中,主线程可以理解为类似进程,协程类似于线程

goroutine调度模型MPG

  • M:主线程,直接运行在操作系统上,为物理线程
  • P:程序运行需要的资源或者说依赖
  • G:协程是一个逻辑程序依赖于M主线程 运行,有自己的栈独立运行
  • M可以有多个,多个M运行在一个cpu上叫做并发,多个M运行在多个cpu叫做并行
  • 如果一个协程发生了阻塞程序会另外开启一个线程把排队的协程引用到这个新开启的M中去,等到M0中的G不再堵塞则再进行M0的调度执行,保证程序得以继续并发执行


golang中设置允许cpu数目



package main

import (
	"fmt"
	"runtime"
)

func main(){
	// runtime.NumCPU() 查看本机有几颗逻辑cpu
	cpunum := runtime.NumCPU()
	fmt.Println(cpunum)

	// runtime.GOMAXPROCS() 可以设置可同时执行最大cpu数目
	runtime.GOMAXPROCS(cpunum-1)
	
	// runtime.Version() 返回go版本字符串,1.8以后默认多核允许不需要设置
	govarson := runtime.Version()
	fmt.Println(govarson)
}
PS E:\...\src\gojson\jsondemo-10-24\cupdemo> go run .\main.go                                     
2
go1.9.2

channel管道