首页
学习
活动
专区
圈层
工具
发布

Go 调度器:一个线程的执行流程

创建指定个数的 p 结构体对象,放在 allp中,并把 m0 和 allp[0] 绑定起来(后续 m0 就不需要绑定 p 了) 源码位置:src/runtime/proc.go 5683 go 体验AI...)) { // 用户代码对 P 数量进行缩减allp = allp[:nprocs]} else { // 这里是初始化nallp := make([]*p,...copy(nallp, allp[:cap(allp)])allp = nallp}...unlock(&allpLock)}// initialize new P's // 循环创建新 P,直到...、初始化 nprocs 个 p 结构体对象,此时 p.status = _Pgcstop,依次保存在 allp 切片之中;先把 allp[0] 状态设置为 _Pidle,然后把 m0 和 allp[0]...关联在一起,即 m0.p = allp[0] , allp[0].m = m0,此时设置 allp[0] 的状态 _Prunning;循环 allp[0] 之外的所有 p 对象,设置 _Pidle 状态

17410
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    详解Go语言调度循环源码实现

    )) { lock(&allpLock) if nprocs allp)) { allp = allp[:nprocs] } else { nallp...:= make([]*p, nprocs) copy(nallp, allp[:cap(allp)]) allp = nallp } unlock(&allpLock) }...() // 不能释放 p 本身,因为他可能在 m 进入系统调用时被引用 } // 释放完 P 之后重置allp的长度 if int32(len(allp)) !...P 状态设置为 _Pdead; 通过截断改变全局变量 allp 的长度保证与期望处理器数量相等; 遍历 allp 检查 P 的是否处于空闲状态,是的话放入到空闲列表中; P.init func (pp...需要注意的是,遍历 allp 时是从随机位置上的 P 开始,防止每次遍历时使用同样的顺序访问allp中的元素; 所有的可能性都尝试过了,在准备休眠 M 之前,还要进行额外的检查; 首先检查此时是否是 GC

    1.5K20

    深入理解Go调度原理和实现

    该函数主要有以下步骤: 计算当前真正p的数量nprocs,初始化保存所有p的全局变量allp,allp为一个切片,它里面保存的对象为*p类型,利用make初始化allp....将m0和allp[0]互相绑定,并将allp[0]状态设置为_Prunning 将allp[1:nprocs]中的p放入到全局变量sched的pidle空闲队列中 上述步骤描述的是最基本的情况,即没有通过...) if nprocs allp)) { // 调整allp的len为nprocs, allp的cap不变 allp = allp[:nprocs] } else...copy(nallp, allp[:cap(allp)]) // 将allp替换为新创建的切片nallp allp = nallp } unlock(&allpLock) }...allp[0](与m0绑定的p)之外的所有的p放入到空闲链表中 for i := nprocs - 1; i >= 0; i-- { p := allp[i] // 如果当前的p是allp[0

    1.4K10
    领券