V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Sponsored by
LinkedIn
2000 个不用坐班的远程好工作在召唤你 · 弹性上班不打卡,工作和生活都能拥有
2000 个不用坐班的全球远程工作,帮助 V2EX 的小伙伴开启全新的工作方式。
Promoted by LinkedIn
Askiz
V2EX  ›  编程

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

  •  
  •   Askiz · 72 天前 · 597 次点击
    这是一个创建于 72 天前的主题,其中的信息可能已经有所发展或是发生改变。
    起因是在学 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  
       72 天前 via Android
    尾递归转循环了吧
    Askiz
        2
    Askiz  
    OP
       72 天前
    @learningman #1 python 和 go 并不支持对尾递归的优化
    misdake
        3
    misdake  
       72 天前
    新线程和协程得到的是一个新的栈。不依赖创建时的栈。
    Askiz
        4
    Askiz  
    OP
       72 天前
    @misdake #3 嗯嗯,如果栈是独立的,那创造无限个独立的栈会溢出吗?
    darklights
        5
    darklights  
       72 天前
    05 秒:创建 coroutine#1 运行 handler#1 ,注册 handler#2 ,coroutine#1 结束
    10 秒:创建 coroutine#2 运行 handler#2 ,注册 handler#3 ,coroutine#2 结束
    ……

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