Go协程机制

Thread vs. Groutine

协程是一个更轻量级的线程 
1.创建时默认的stack的大小
JDK5 以后JAVA Thread stack 默认为1M
Groutine的Stack初始化大小为2K  创建起来会更快
2.和KSE(Kernel Space Entity)的对应关系
JAVA Thread是1:1
Groutine是M:N

Kernel Space Entity 系统线程由CPU直接调度,调度效率高
线程切换的时候,会引起内核线程context切换的行为,大消耗,协程多对一,所以切换的消耗更小

在这里插入图片描述

Go基本调度机制

在这里插入图片描述

M    系统线程 kernel entity
P		Processsor Go语言实现的协程处理器
G		Goroutine 协程
每一个Go Processor都挂在系统线程上,并且有一个协程执行队列,依次运行协程,一个协程运行的事件特别长,Go会有 守护进程计数,记录每个Processor完成的协程的数量 ,完成的协程数量在一段时间内没有明显的变化,就会在协程任务栈上插入一个明显的标记,当协程运行的时候遇到非内联函数,就会读到这个标记,就会中断自己,把自己插入到等待协程的任务队列中,切换成别的协程。
 另一个提升并发数量的机制设计的是:系统中断了I/O等,需要等待的时候,为了提高整体并发,Processor会把自己移动到另一个可以使用的System Thread当中,继续执行他所挂载的其他队列中的协程,当被中断的协程被唤醒,会把自己加入到某个Processor的等待队列中,或者加入到全局等待队列中,当一个协程被中断的时候,它的寄存器状态也会保存到这个协程对象里,当协程再次获得运行的机会时,重新写入寄存器,继续运行。
 Go的携程机制和系统线程多对多的关系,如何高效的利用系统线程,尽量多的运行并发的协程任务

示例代码

Go 协程 关键字是go

package goroutine_test

import (
	"fmt"
	"testing"
	"time"
)

func TestGroutine(t *testing.T){
	for i:=0;i<10;i++{
		go func (i int){
			fmt.Println(i)
		}(i)
		/*
			如果使用匿名变量 不在()内填写,就会导致出现竞态条件,使用锁机制完成
		  	在Test以及它启动的协程上,被共享了,必须用锁

			Go的方法调用的传递都是值传递,传递i的同时复制了i的值,每个携程上拥有的i的地址是不同的
			不会出现竞争关系,可以正确执行但是乱序而已
		*/
	}
time.Sleep(time.Millisecond*20)
//协程的调度顺序和方法的调度顺序不相同
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>