V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Askiz
V2EX  ›  编程

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

  •  
  •   Askiz · 331 天前 · 855 次点击
    这是一个创建于 331 天前的主题,其中的信息可能已经有所发展或是发生改变。
    起因是在学 openresty 的时候官方 lua-nginx-module 里官方介绍 ngx.timer.at 的使用方法,介绍了一种定时器的写法


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


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


    上面这两个也并不会产生栈溢出,请问这是为什么呢?
    7 条回复    2022-07-14 23:19:00 +08:00
    learningman
        1
    learningman  
       331 天前 via Android
    尾递归转循环了吧
    Askiz
        2
    Askiz  
    OP
       331 天前
    @learningman #1 python 和 go 并不支持对尾递归的优化
    misdake
        3
    misdake  
       331 天前
    新线程和协程得到的是一个新的栈。不依赖创建时的栈。
    Askiz
        4
    Askiz  
    OP
       331 天前
    @misdake #3 嗯嗯,如果栈是独立的,那创造无限个独立的栈会溢出吗?
    darklights
        5
    darklights  
       331 天前
    05 秒:创建 coroutine#1 运行 handler#1 ,注册 handler#2 ,coroutine#1 结束
    10 秒:创建 coroutine#2 运行 handler#2 ,注册 handler#3 ,coroutine#2 结束
    ……

    并没有无限递归
    djoiwhud
        6
    djoiwhud  
       331 天前 via Android
    go 的例子显然不是递归。
    你只是不停的创建 goroutine ,这个是生成了一个 goroutine 运行时环境,然后这个运行时环境很快就退出了回收了(调度线程回收了)。
    你要是不用 goroutine ,必然会溢出。
    Askiz
        7
    Askiz  
    OP
       331 天前 via Android
    @darklights 嗯嗯 谢谢解答
    关于   ·   帮助文档   ·   博客   ·   nftychat   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2315 人在线   最高记录 5634   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 00:10 · PVG 08:10 · LAX 17:10 · JFK 20:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.