ST源码分析-退出处理 - 弦外之音

/ 0评 / 0

在文章《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; 永远不会执行。


相关阅读:


由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。QQ:2338195090。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注