理解Python守护线程
我显然对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 个回答
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
对我来说,这看起来挺正常的。
13
你对守护线程应该做什么的理解是正确的。
至于为什么没有发生这种情况,我猜测你可能在使用旧版本的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
成员)