在函数中开启协程或进程递归调用自身会引起栈溢出吗?

2022-07-14 22:19:30 +08:00
 Askiz
起因是在学 openresty 的时候官方 lua-nginx-module 里官方介绍 ngx.timer.at 的使用方法,介绍了一种定时器的写法


这是用递归调用实现的定时器,查看源码 ngx.timer.at 是异步的,使用时是创建一个 coroutine 运行子函数。
一般来说无限递归调用自身会导致栈溢出,但是这个例子我测试了并不会栈溢出。
于是测试了 golang 的在函数中开启协程递归调用自身:


测试 python3 在函数中开启线程递归调用自身:


上面这两个也并不会产生栈溢出,请问这是为什么呢?
1179 次点击
所在节点    编程
7 条回复
learningman
2022-07-14 22:23:07 +08:00
尾递归转循环了吧
Askiz
2022-07-14 22:25:31 +08:00
@learningman #1 python 和 go 并不支持对尾递归的优化
misdake
2022-07-14 22:42:58 +08:00
新线程和协程得到的是一个新的栈。不依赖创建时的栈。
Askiz
2022-07-14 22:54:15 +08:00
@misdake #3 嗯嗯,如果栈是独立的,那创造无限个独立的栈会溢出吗?
darklights
2022-07-14 23:04:30 +08:00
05 秒:创建 coroutine#1 运行 handler#1 ,注册 handler#2 ,coroutine#1 结束
10 秒:创建 coroutine#2 运行 handler#2 ,注册 handler#3 ,coroutine#2 结束
……

并没有无限递归
djoiwhud
2022-07-14 23:08:56 +08:00
go 的例子显然不是递归。
你只是不停的创建 goroutine ,这个是生成了一个 goroutine 运行时环境,然后这个运行时环境很快就退出了回收了(调度线程回收了)。
你要是不用 goroutine ,必然会溢出。
Askiz
2022-07-14 23:19:00 +08:00
@darklights 嗯嗯 谢谢解答

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/866253

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX