当前位置: 首页 > news >正文

网站建站服务的公司h5企业模板网站

网站建站服务的公司,h5企业模板网站,怎么做网页版手机版网站,大学生ppt自我介绍幻灯片上一讲说到调度器将maingoroutine推上舞台#xff0c;为它铺好了道路#xff0c;开始执行runtime.main函数。这一讲#xff0c;我们探索maingoroutine以及普通goroutine从执行到退出的整个过程。 //Themaingoroutine. funcmain(){ //gmaingoroutine#xff0c;不再是g0了 …上一讲说到调度器将maingoroutine推上舞台为它铺好了道路开始执行runtime.main函数。这一讲我们探索maingoroutine以及普通goroutine从执行到退出的整个过程。 //Themaingoroutine. funcmain(){ //gmaingoroutine不再是g0了 g:getg()//……………………ifsys.PtrSize8{ maxstacksize1000000000 }else{ maxstacksize250000000 }//AllownewproctostartnewMs. mainStartedtruesystemstack(func(){ //创建监控线程该线程独立于调度器不需要跟p关联即可运行 newm(sysmon,nil) })lockOSThread()ifg.m!m0{ throw(runtime.mainnotonm0) }//调用runtime包的初始化函数由编译器实现 runtime_init()//mustbebeforedefer ifnanotime()0{ throw(nanotimereturningzero) }//Deferunlocksothatruntime.Goexitduringinitdoestheunlocktoo. needUnlock:true deferfunc(){ ifneedUnlock{ unlockOSThread() } }()//Recordwhentheworldstarted.Mustbeafterruntime_init //becausenanotimeonsomeplatformsdependsonstartNano. runtimeInitTimenanotime()//开启垃圾回收器 gcenable()main_init_donemake(chanbool)//……………………//main包的初始化递归的调用我们import进来的包的初始化函数 fn:main_init fn() close(main_init_done)needUnlockfalse unlockOSThread()//……………………//调用main.main函数 fnmain_main fn() ifraceenabled{ racefini() }//……………………//进入系统调用退出进程可以看出maingoroutine并未返回而是直接进入系统调用退出进程了 exit(0) //保护性代码如果exit意外返回下面的代码会让该进程crash死掉 for{ varx*int32 *x0 } }main函数执行流程如下图 从流程图可知maingoroutine执行完之后就直接调用exit(0)退出了这会导致整个进程退出太粗暴了。 不过maingoroutine实际上就是代表用户的main函数它都执行完了肯定是用户的任务都执行完了直接退出就可以了就算有其他的goroutine没执行完同样会直接退出。 packagemainimportfmtfuncmain(){ gofunc(){fmt.Println(helloqcrao.com)}() }在这个例子中maingorutine退出时还来不及执行go出去的函数整个进程就直接退出了打印语句不会执行。因此maingoroutine不会等待其他goroutine执行完再退出知道这个有时能解释一些现象比如上面那个例子。 这时心中可能会跳出疑问我们在新创建goroutine的时候不是整出了个“偷天换日”风风火火地设置了goroutine退出时应该跳到runtime.goexit函数吗怎么这会不用了闲得慌 回顾一下上一讲的内容跳转到main函数的两行代码 //把sched.pc值放入BX寄存器 MOVQ gobuf_pc(BX),BX //JMP把BX寄存器的包含的地址值放入CPU的IP寄存器于是CPU跳转到该地址继续执行指令 JMP BX直接使用了一个跳转并没有使用CALL指令而runtime.main函数中确实也没有RET返回的指令。所以maingoroutine执行完后直接调用exit(0)退出整个进程。 那之前整地“偷天换日”还有用吗有的这是针对非maingoroutine起作用。 参考资料【阿波张非goroutine的退出】中用调试工具验证了非maingoroutine的退出感兴趣的可以去跟着实践一遍。 我们继续探索非maingoroutine后文我们就称gp好了的退出流程。 gp执行完后RET指令弹出goexit函数地址实际上是funcPC(goexit)1CPU跳转到goexit的第二条指令继续执行 //src/runtime/asm_amd64.s//Thetop-mostfunctionrunningonagoroutine //returnstogoexitPCQuantum. TEXTruntime·goexit(SB),NOSPLIT,$0-0 BYTE $0x90 //NOP CALL runtime·goexit1(SB) //doesnotreturn //tracebackfromgoexit1musthitcoderangeofgoexit BYTE $0x90 //NOP直接调用runtime·goexit1 //src/runtime/proc.go //Finishesexecutionofthecurrentgoroutine. funcgoexit1(){ //…………………… mcall(goexit0) }调用mcall函数 //切换到g0栈执行fn(g) //Fn不能返回 TEXTruntime·mcall(SB),NOSPLIT,$0-8 //取出参数的值放入DI寄存器它是funcval对象的指针此场景中fn.fn是goexit0的地址 MOVQ fn0(FP),DIget_tls(CX) //AXg MOVQ g(CX),AX //savestateing-sched //mcall返回地址放入BX MOVQ 0(SP),BX //callersPC //g.sched.pcBX保存g的PC MOVQ BX,(g_schedgobuf_pc)(AX) LEAQ fn0(FP),BX //callersSP //保存g的SP MOVQ BX,(g_schedgobuf_sp)(AX) MOVQ AX,(g_schedgobuf_g)(AX) MOVQ BP,(g_schedgobuf_bp)(AX)//switchtom-g0itsstack,callfn MOVQ g(CX),BX MOVQ g_m(BX),BX //SIg0 MOVQ m_g0(BX),SI CMPQ SI,AX //ifgm-g0callbadmcall JNE3(PC) MOVQ $runtime·badmcall(SB),AX JMPAX //把g0的地址设置到线程本地存储中 MOVQ SI,g(CX) //gm-g0 //从g的栈切换到了g0的栈D MOVQ (g_schedgobuf_sp)(SI),SP //spm-g0-sched.sp //AXg参数入栈 PUSHQ AX MOVQ DI,DX //DI是结构体funcval实例对象的指针它的第一个成员才是goexit0的地址 //读取第一个成员到DI寄存器 MOVQ 0(DI),DI //调用goexit0(g) CALL DI POPQ AX MOVQ $runtime·badmcall2(SB),AX JMPAX RET函数参数是 typefuncvalstruct{ fnuintptr //variable-size,fn-specificdatahere }字段fn就表示goexit0函数的地址。 L5将函数参数保存到DI寄存器这里fn.fn就是goexit0的地址。 L7将tls保存到CX寄存器L9将当前线程指向的goroutine非maingoroutine称为gp保存到AX寄存器L11将调用者调用mcall函数的栈顶这里就是mcall完成后的返回地址存入BX寄存器。 L13将mcall的返回地址保存到gp的g.sched.pc字段L14将gp的栈顶也就是SP保存到BX寄存器L16将SP保存到gp的g.sched.sp字段L17将g保存到gp的g.sched.g字段L18将BP保存到gp的g.sched.bp字段。这一段主要是保存gp的调度信息。 L21将当前指向的g保存到BX寄存器L22将g.m字段保存到BX寄存器L23将g.m.g0字段保存到SIg.m.g0就是当前工作线程的g0。 现在SIg0AXgpL25判断gp是否是g0如果gpg0说明有问题执行runtime·badmcall。正常情况下PC值加3跳过下面的两条指令直接到达L30。 L30将g0的地址设置到线程本地存储中L32将g0.SP设置到CPU的SP寄存器这也就意味着我们从gp栈切换到了g0的栈要变天了 L34将参数gp入栈为调用goexit0构造参数。L35将DI寄存器的内容设置到DX寄存器DI是结构体funcval实例对象的指针它的第一个成员才是goexit0的地址。L36读取DI第一成员也就是goexit0函数的地址。 L40调用goexit0函数这已经是在g0栈上执行了函数参数就是gp。 到这里就会去执行goexit0函数注意这里永远都不会返回。所以在CALL指令后面如果返回了又会去调用runtime.badmcall2函数去处理意外情况。 来继续看goexit0 //goexitcontinuationong0. //在g0上执行 funcgoexit0(gp*g){ //g0 _g_:getg()casgstatus(gp,_Grunning,_Gdead) ifisSystemGoroutine(gp){ atomic.Xadd(sched.ngsys,-1) }//清空gp的一些字段 gp.mnil gp.lockedmnil _g_.m.lockedgnil gp.paniconfaultfalse gp._defernil//shouldbetruealreadybutjustincase. gp._panicnil//non-nilforGoexitduringpanic.pointsatstack-allocateddata. gp.writebufnil gp.waitreason gp.paramnil gp.labelsnil gp.timernil//Notethatgpsstackscanisnowvalidbecauseithasno //stack. gp.gcscanvalidtrue //解除g与m的关系 dropg()if_g_.m.locked^_LockExternal!0{ print(invalidm-locked,_g_.m.locked,\n) throw(internallockOSThreaderror) } _g_.m.locked0 //将g放入free队列缓存起来 gfput(_g_.m.p.ptr(),gp) schedule() }它主要完成最后的清理工作 1.把g的状态从_Grunning更新为_Gdead 1.清空g的一些字段 1.调用dropg函数解除g和m之间的关系其实就是设置g-mnil,m-currgnil 1.把g放入p的freeg队列缓存起来供下次创建g时快速获取而不用从内存分配。freeg就是g的一个对象池 1.调用schedule函数再次进行调度。 到这里gp就完成了它的历史使命功成身退进入了goroutine缓存池待下次有任务再重新启用。 而工作线程又继续调用schedule函数进行新一轮的调度整个过程形成了一个循环。 总结一下maingoroutine和普通goroutine的退出过程 对于maingoroutine在执行完用户定义的main函数的所有代码后直接调用exit(0)退出整个进程非常霸道。 对于普通goroutine则没这么“舒服”需要经历一系列的过程。先是跳转到提前设置好的goexit函数的第二条指令然后调用runtime.goexit1接着调用mcall(goexit0)而mcall函数会切换到g0栈运行goexit0函数清理goroutine的一些字段并将其添加到goroutine缓存池里然后进入schedule调度循环。到这里普通goroutine才算完成使命。 本文节选于Go合集《Go 语言问题集》GOLANG ROADMAP 一个专注Go语言学习、求职的社区。
http://www.pierceye.com/news/877596/

相关文章:

  • 网站在政务新媒体建设方案打开手机网站速度慢
  • 网站备案表服务类网站模板
  • 个人网站维护费用淮安注册公司
  • 网站提交做海鱼的网站
  • 建设网站业务竞争大唯一做魅惑的网站
  • 建设学校网站的意义更换wordpress图标
  • 环保局网站如何做备案证明在线代理服务器网页版
  • 十佳网站武昌做网站哪家好
  • wordpress调用同分类最新文章seo营销网站的设计标准
  • 免费下载网站有哪些连云港网络公司排名
  • 如何迅速建企业网站毕设做网站需要什么技术准备
  • 可以做音基题的音乐网站公司网页设计怎么弄
  • 益阳营销型网站建设乌鲁木做兼职的网站
  • 如何建单位网站怎么让别人找你做网站
  • 青海建设厅职称网站建设小程序怎么挂失
  • 建设在线购物网站51zwd一起做网站广州
  • 如何制作网站图片帮忙做网站
  • 高端做网站公司网络信息安全公司
  • 手机网站图片自适应建设网站用的软件
  • wordpress postid随机苏州百度推广排名优化
  • 重庆企业网站推广服务做性的网站
  • asp.net 创建网站登陆建设银行网站异常
  • 柳州网站建设柳州wordpress 创建文集
  • 怎样把网站做成app多语言网站建设方案
  • 中国最新新闻头条南通百度网站快速优化
  • 乐清网站推广制作长沙银狐做网站
  • 做企业网站需要多久论坛网站推广方案
  • 郑州网站优化排名wordpress搭建本地博客
  • 如何获取网站域名证书刚刚北京传来重大消息
  • 找别人做淘客网站他能改pid吗现在中型公司做网站用的是什么框架