python 多线程threading setDeamon()和join()可以只用其一吗?

creazyloser
  • 36

看了很多文档,感觉大家写的互相都有些矛盾。

我现在假如要实现这样的需求:

主线程不等待子线程,但是主线程结束时,子线程仍能继续单独运行。

这种情况下,我试了下,似乎 setDeamon 设为为 False, 不加 join() 就可以满足。是这样吗?

然后抛开这个需求不说,如果加了 join(), 写不写 setDeamon() 或者 setDeamonTrueFalse
并没有什么影响,都是等主线程等待子线程结束才执行,但我看网上很多文档都是 setDeamonjoin 一起用的,不懂这样用的好处在哪里?

回复
阅读 3.2k
2 个回答

你得考虑意外退出的情况,比如ctrl-c

weapon
  • 3.2k

先看看题主的需求

主线程不等待子线程,但是主线程结束时,子线程仍能继续单独运行。

这个需求弄不了,因为主线程退出后,所有子线程都会结束,与有没有设置 setDeamon 无关,当主线程结束后,python将销毁运行时环境。

setDeamon 在这其中会有一点点区别,如果 setDaemon(False) ,主线程将等待该线程结束,等同于你调用线程的 join 方法。如果 setDaemon(True) ,那么和之前一样,主线程结束,所有子线程都将结束,不会等待子线程运行结束。

------- 分割线 -------
被踩了??? 啊? 哪说错了啊。主线程将等待该线程结束,所有子线程都会退出的啊,翻源码来说明,好气啊。
代码在 Lib/threading.py 中:

_main_thread = _MainThread()

def _shutdown():
    assert tlock is not None
    assert tlock.locked()
    tlock.release()
    _main_thread._stop()
    t = _pickSomeNonDaemonThread()
    while t:
        t.join()
        t = _pickSomeNonDaemonThread()
    _main_thread._delete()

def _pickSomeNonDaemonThread():
    for t in enumerate():
        if not t.daemon and t.is_alive():
            return t
    return None

_main_thread 就是主线程,当主线程关闭后,通过 _pickSomeNonDaemonThread() 函数筛选出不是守护线程的 (t.daemon 为 False)的,然后通过 t.join() 等待他们的结束。而 setDaemon(True) 的线程就没管了。
所以那个需求就是不行啊。如果是子线程里有个死循环,并且他是 setDaemon(False) ,那他永远也不会结束啊。主线程肯定也不会结束啊。踩我的请给我个理由好吗。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏