美文网首页程序员
go 协程的实现笔记

go 协程的实现笔记

作者: yellowone | 来源:发表于2020-07-14 17:28 被阅读0次

看到有一篇写得很清楚的博客,做个笔记。

原文在此:Golang源码探索(二) 协程的实现原理

  • 有时候G需要调用一些无法避免阻塞的原生代码, 这时M会释放持有的P并进入阻塞状态, 其他M会取得这个P并继续运行队列中的G.

  • 因为同一时间只有一个线程(M)可以拥有P, P中的数据都是锁自由(lock free)的, 读写这些数据的效率会非常的高.

  • 自旋中(spinning)这个状态非常重要, 是否需要唤醒或者创建新的M取决于当前自旋中的M的数量.

  • 本地运行队列有数量限制, 当数量达到256个时会入队到全局运行队列. 本地运行队列的数据结构是环形队列, 由一个256长度的数组和两个序号(head, tail)组成.

  • 全局运行队列的数据结构是链表, 由两个指针(head, tail)组成.

  • 入队待运行的G后, 如果当前无自旋的M但是有空闲的P, 就唤醒或者新建一个M

  • 当M离开自旋状态并准备运行出队的G时, 如果当前无自旋的M但是有空闲的P, 就唤醒或者新建一个M

  • 当M离开自旋状态并准备休眠时, 会在离开自旋状态后再次检查所有运行队列, 如果有待运行的G则重新进入自旋状态

  • G从无缓冲的channel获取不到数据, G会保存状态并变为等待中(_Gwaiting)并添加到channel的队列

  • go的调用规范非常的简单, 所有参数都通过栈传递, 返回值也通过栈传递

  • 参数和返回值都从低位到高位排列, go函数可以有多个返回值的原因也在于此. 因为返回值都通过栈传递了

  • TLS的全称是Thread-local storage, 代表每个线程的中的本地数据.

  • 当函数发现栈空间不足时, 会申请一块新的栈空间并把原来的栈内容复制过去.

  • 传递闭包给其他函数时会传递指向"闭包的内容"的指针

  • 如果闭包修改了变量, 闭包中的参数会是指针而不是值, 修改时会修改到原来的位置上

  • m0是启动程序后的主线程, 这个m对应的实例会在全局变量m0中, 不需要在heap上分配,

  • m0负责执行初始化操作和启动第一个g, 在之后m0就和其他的m一样了.

  • g0是仅用于负责调度的G, g0不指向任何可执行的函数, 每个m都会有一个自己的g0,

  • 在调度或系统调用时会使用g0的栈空间, 全局变量的g0是m0的g0.

  • g0会被设置到TLS中

  • 第一个被调度的G会运行runtime.main

  • 启动一个新的M执行sysmon函数, 这个函数会监控全局的状态并对运行时间过长的G进行抢占

  • G中保存调度数据是sched变量

  • M中的g0是用于调度的特殊g, 调度和执行系统调用时会切换到这个g

  • M获取g0就是从TLS中获取。

  • 如果当前有空闲的P, 但是无自旋的M(nmspinning等于0), 并且主函数已执行则唤醒或新建一个M.

  • 为了公平起见, 每61次调度从全局运行队列获取一次G, (一直从本地获取可能导致全局运行队列中的G不被运行)

  • sysmon中有netpool(获取fd事件), retake(抢占), forcegc(按时间强制执行gc), scavenge heap(释放自由列表中多余的项减少内存占用)等处理.

  • 通过设置stackguard可以实现抢占,因为会触发栈扩张,栈扩张的时候检查是否等于一个特殊的常量,如果是,协程自身判断是否要抢占。

  • 被枪占的g会到全局队列g中。

相关文章

  • go的协程并发-channel消息机制

    go的协程并发-channel消息机制 方式一 方式二 go-协程实现方案汇总

  • 【初探协程】之深入分析Yield原理

    最近在学习协程,目前Php实现协程的方式有yield和swoole扩展,另外可实现协程技术的还有Go语言。本文主要...

  • Go协程介绍

    参考自《go专家编程》Go协程所实现的是M:N的线程模型,M个协程运行在N个线程中。 1. MPG模型 Go协程中...

  • go 协程的实现笔记

    看到有一篇写得很清楚的博客,做个笔记。 原文在此:Golang源码探索(二) 协程的实现原理 有时候G需要调用一些...

  • Golang 协程和管道

    1.协程(goroutiue) 在go语言中,并发的实现是通过协程来实现的。语法上使用go关键字加函数即可让函数以...

  • 21. Go 协程

    21. Go 协程 Go 协程是什么? Go 协程是与其他函数或方法一起并发运行的函数或方法。Go 协程可以看作是...

  • 韩天峰 - Swoole4-全新的PHP编程模式2018-10-

    介绍 Swoole 2.2 全新协程引擎底层实现原理 2. Go(协程)+ Chan(通道)实现有别于传统 PHP...

  • 关于Coroutine\Channel的几点注意

    通道,类似于go语言的chan,支持多生产者协程和多消费者协程。底层自动实现了协程的切换和调度。 实现原理 通道与...

  • go 协程实现

    [TOC] go 协程执行过程 1. 生成g,并放入队列 用户调用go时,编译器会会调用runtime.newpr...

  • 深入学习Kotlin协程(一)-协程是什么?

    Kotlin协程是什么? 协程并不是Kotlin提出的,其他的一些编程语言在早期就已经实现了协程,比如: Go、P...

网友评论

    本文标题:go 协程的实现笔记

    本文链接:https://www.haomeiwen.com/subject/ljpfhktx.html