ST源码分析-退出处理

SRS 的社群来了,想加入微信社群的朋友请购买《SRS原理》电子书,里有更高级的内容与答疑服务。


在文章《ST源码分析-st_thread_exit》分析 lookupdns 的时候,当时没有仔细讲解 lookupdns 的退出处理。主要有两个退出处理。

1,do_resolve() 普通协程函数的退出处理。

2,main(),始祖协程函数的退出处理。


do_resolve() 的流程图如下:

如上图所示,会阻塞在 st_recvfrom()。最后 return NULL ,但是有一个问题,st_thread_create() 创建协程函数 do_resolve() 的时候,使用了 _st_stack_new() 申请了一块内存,此时此刻 do_resolve() 已经执行完 return NULL ,之前申请的 内存怎么处理?return NULL 之后,代码逻辑会跳到哪里?

首先, do_resolve() 运行的地方是 _st_thread_main(),如下图:

所以 do_resolve() 的 return NULL 执行完之后,是回到 _st_thread_main() 函数的。就会又执行一次 st_thread_exit()

此时,是 第二次执行 st_thread_exit(),第一次是在 main() 。

回到之前的问题,_st_stack_new() 申请的内存 在何时释放?

解答:在 st_thread_exit()里面处理,如下图:

从上图可以看到,如果当前协程不是 始祖协程 ,就会调 _st_stack_free() 函数 把内存 放进去全局变量 _st_free_stacks ,下次申请内存就可以直接从 _st_free_stacks 拿。

所以,分析到这里, do_resolve() 的周期就结束了,函数走完了,然后之前申请的内存也放进去内存池里面,_ST_RUNQ 队列也没有了 do_resolve() 。

所以相当于 do_resolve() 协程已经退出了。

接下来分析始祖协程是如何退出的。始祖协程就是 main() 函数,他当时已经执行到了,st_thread_exit(NULL);,如下图:

始祖协程会不断在 st_thread_exit() 里面 递归调用 _st_vp_schedule() 进行协程调度,其他协程结束之后,就会停在 idle_thread 里面,看看 _st_idle_thread_start() 函数的代码,如下图:

从上图可以看出,由于已经没有 active 的协程,所以 _st_idle_thread_start() 会直接退出整个程序,至此,始祖协程也就退出了。main() 函数的最后一行代码 return 1; 永远不会执行。


由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Loken2020

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值