Golang-gopark函数和goready函数原理分析

本文深入探讨了Golang中gopark和goready函数的底层原理,涉及协程切换、堆栈切换、状态机管理和调度器的工作。gopark用于将协程置于等待状态并执行schedule(),而goready则负责唤醒协程并将其置于可运行状态,等待调度执行。
摘要由CSDN通过智能技术生成

Golang-gopark函数和goready函数原理分析

前面介绍的scheduler和channel里面都与gopark和goready这两个函数紧密相关,但是站在上层可以理解这两个函数的作用,但是出于对源码探索,我们要明白这两个函数不仅仅做了啥,还要知道怎么做的。本文主要内容是从底层源码分析这两个函数原理:

  1. gopark函数
  2. goready函数

gopark函数

gopark函数在协程的实现上扮演着非常重要的角色,用于协程的切换,协程切换的原因一般有以下几种情况:

  1. 系统调用;
  2. channel读写条件不满足;
  3. 抢占式调度时间片结束;

gopark函数做的主要事情分为两点:

  1. 解除当前goroutine的m的绑定关系,将当前goroutine状态机切换为等待状态;
  2. 调用一次schedule()函数,在局部调度器P发起一轮新的调度。

下面我们来研究一下gopark函数是怎么实现协程切换的。

先看看源码:

func gopark(unlockf func(*g, unsafe.Pointer) bool, lock unsafe.Pointer, reason waitReason, traceEv byte, traceskip int) {
   
	if reason != waitReasonSleep {
   
		checkTimeouts() // timeouts may expire while two goroutines keep the scheduler busy
	}
	mp := acquirem()
	gp := mp.curg
	status := readgstatus(gp)
	if status != _Grunning && status != _Gscanrunning {
   
		throw("gopark: bad g status")
	}
	mp.waitlock = lock
	mp.waitunlockf = *(*unsafe.Pointer)(unsafe.Pointer(&unlockf))
	gp
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值