理解Python守护线程

11

我显然对Python线程对象的守护进程属性有一些基本的误解。

请考虑以下内容:

daemonic.py

import sys, threading, time

class TestThread(threading.Thread):
    def __init__(self, daemon):
        threading.Thread.__init__(self)
        self.daemon = daemon

    def run(self):
        x = 0
        while 1:
            if self.daemon:
                print "Daemon :: %s" % x
            else:
                print "Non-Daemon :: %s" % x
            x += 1
            time.sleep(1)

if __name__ == "__main__":
    print "__main__ start"
    if sys.argv[1] == "daemonic":
        thread = TestThread(True)
    else:
        thread = TestThread(False)
    thread.start()
    time.sleep(5)
    print "__main__ stop"

根据Python文档:

当没有非守护线程存在时,整个Python程序将退出。

因此,如果我将TestThread作为守护进程运行,我期望它在主线程完成后退出。但是事实并非如此:

> python daemonic.py daemonic
__main__ start
Daemon :: 0
Daemon :: 1
Daemon :: 2
Daemon :: 3
Daemon :: 4
__main__ stop
Daemon :: 5
Daemon :: 6
^C

我哪里理解不了?


正如Justin和Brent猜测的那样,我使用的是Python 2.5。回到家后,我尝试在自己的机器上运行2.7版本,一切都运行良好。感谢你们的帮助!

2个回答

13
您对守护线程(daemon threads)的理解是正确的。至于为什么不起作用,我猜测您正在使用较旧版本的Python。Python 2.5.4文档中包括一个 setDaemon(daemonic) 函数,以及 isDaemon() 来检查线程是否为守护线程。2.6文档则将这些函数替换为可直接修改的 daemon 标志。 参考资料: http://docs.python.org/release/2.5.4/(没有提到 daemon 成员) http://docs.python.org/release/2.6/library/threading.html(包括 daemon 成员)

没意识到在2.7中isDaemonsetDaemon已经基本被弃用了。知道了就好。 - Brent Writes Code

6

只是出于好奇,你使用的是哪个操作系统以及哪个版本的Python?

我在Mac OS X 10.5.8上使用Python 2.6.2。

当我运行你的脚本时,这是我得到的结果:

bnash-macbook:Desktop bnash$ python daemon.py daemonic
__main__ start
Daemon :: 0
Daemon :: 1
Daemon :: 2
Daemon :: 3
Daemon :: 4
__main__ stop
Exception in thread Thread-1 (most likely raised during interpreter shutdown)

这似乎正是您所期望的。

这里是相应的非守护进程行为(直到我杀死该进程):

bnash-macbook:Desktop bnash$ python daemon.py asdf    
__main__ start
Non-Daemon :: 0
Non-Daemon :: 1
Non-Daemon :: 2
Non-Daemon :: 3
Non-Daemon :: 4
__main__ stop
Non-Daemon :: 5
Non-Daemon :: 6
Non-Daemon :: 7
Non-Daemon :: 8
Terminated

对我来说看起来很正常。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接