V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
chaleaoch
V2EX  ›  Python

Python 中线程的 is_alive() 返回 Flase 意味着 线程资源已经被回收了吗?

  •  
  •   chaleaoch · 2020-12-16 23:54:40 +08:00 · 2644 次点击
    这是一个创建于 1437 天前的主题,其中的信息可能已经有所发展或是发生改变。

    线程资源已经被销毁?

    它的子线程会被自动回收吗?

    以下代码输出

    test1
    aps
    irr
    irr
    irr
    

    没想明白为什么.

    代码如下

    import threading
    import time
    
    
    def irr():
        print('irr')
    
    
    def aps():
        print('aps')
        while True:
            time.sleep(6)
            irr()
    
    
    def view():
        t2 = threading.Thread(target=aps)
        t2.daemon = True
        t2.start()
        print('test1')
    
    
    t = threading.Thread(target=view)
    t.daemon = True
    t.start()
    while True:
        time.sleep(1)
    
    
    
    10 条回复    2020-12-17 18:06:01 +08:00
    weyou
        1
    weyou  
       2020-12-17 02:08:04 +08:00 via Android
    输出没问题啊,后面是一直输出 irr 。
    chaleaoch
        2
    chaleaoch  
    OP
       2020-12-17 09:58:47 +08:00
    @weyou 给我感觉好像 python 没有 父子线程的概念. 父线程退出 子线程还活着.
    lanshee
        3
    lanshee  
       2020-12-17 10:53:47 +08:00
    小白问下,这个父线程退出了嘛?
    cbiqih
        4
    cbiqih  
       2020-12-17 12:18:36 +08:00
    设置了 daemon = True, 则为守护进程, 要等所有子进程退出了, 父进程才会结束的~
    4everLoveU
        5
    4everLoveU  
       2020-12-17 15:14:34 +08:00
    主线程显然不会退出啊,设置守护线程,必须等待所有守护线程结束之后才会退出
    chaleaoch
        6
    chaleaoch  
    OP
       2020-12-17 17:16:45 +08:00
    @4everLoveU
    @cbiqih

    这个代码是 主线程 起了一个 子线程 子线程起了一个孙线程.

    现在 子线程结束释放了 但是孙线程还在.

    我的问题是, 为什么孙线程没有被强制释放.


    后来调查了一下.好像 python 里面没有父子概念, 只有主线程和非主线程.

    上面代码里面的例子, 那两个线程实际上是兄弟关系. 所以 view 线程跑完了 aps 还活着.
    xx6412223
        7
    xx6412223  
       2020-12-17 17:18:58 +08:00   ❤️ 1
    楼上解释的都是小问题:
    非守护线程一般作为 main thread, 在非守护线程挂掉之前,程序不会退出(排除异常场景)
    daemon =true 是守护线程,程序退出后他们也随着挂了,所以一般用作垃圾回收,心跳等工作。
    xx6412223
        8
    xx6412223  
       2020-12-17 17:21:54 +08:00   ❤️ 1
    补充一下,除了语言层有特殊设定,线程的生命周期没有父子关系
    4everLoveU
        9
    4everLoveU  
       2020-12-17 17:39:28 +08:00   ❤️ 1
    线程的父对象都是 Thread,所有基于 Thread 创建的线程都是平等的,逻辑上看着是多重派生,实际上不存在什么父子关系,每个线程都是在自己的隔离环境中运行的

    主线程就是当前脚本的运行线程及其环境,t/t2 都是主线程中的守护线程,不存在 t2 是 t 线程中的一个隔离线程,所以你说的兄弟关系比较恰当。
    weyou
        10
    weyou  
       2020-12-17 18:06:01 +08:00   ❤️ 1
    @chaleaoch 线程的行为是操作系统决定的, 而不是语言. 各种语言的线程库只是对操作系统线程的封装.

    线程只有主线程和子线程的概念, 没听说过"父线程"的说法. 通过子线程创建的子线程和子线程本身并没有本质区别. 所以你这里的父线程(非主线程)退出子线程还活着. 而主线程退出的话, 分两种情况:
    a.) 如果此时还有非 daemon 的子线程存在, 主线程就会继续等待, 直到所有非 daemon 子线程退出才会退出.
    b.) 如果此时只剩下 daeomon 子线程, 所有的 daemon 子线程都被强制结束掉, 然后主线程退出.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2154 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 00:48 · PVG 08:48 · LAX 16:48 · JFK 19:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.