Understanding Python daemon threads
I've obviously misunderstood something fundamental about a Python Thread object's daemon开发者_如何转开发 attribute.
Consider the following:
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"
From the python docs:
The entire Python program exits when no alive non-daemon threads are left.
So if I run with TestThread as a daemon, I would expect it to exit once the main thread has completed. But this doesn't happen:
> python daemonic.py daemonic
__main__ start
Daemon :: 0
Daemon :: 1
Daemon :: 2
Daemon :: 3
Daemon :: 4
__main__ stop
Daemon :: 5
Daemon :: 6
^C
What don't I get?
As guessed by Justin and Brent, I was running with Python 2.5. Have just got home and tried out on my own machine running 2.7, and everything works fine. Thanks for your helps!
Your understanding about what daemon threads should do is correct.
As to why this isn't happening, I am guessing you are using an older version of Python. The Python 2.5.4 docs include a setDaemon(daemonic)
function, as well as isDaemon()
to check if a thread is a daemon thread. The 2.6 docs replace these with a directly modifiable daemon
flag.
References:
http://docs.python.org/release/2.5.4/ (no daemon
member mentioned)
http://docs.python.org/release/2.6/library/threading.html (includes daemon
member)
Just out of curiosity, what OS and what version of python are you running?
I'm on Python 2.6.2 on Mac OS X 10.5.8.
When I run your script, here's what I get:
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)
Which seems like exactly what you'd expect.
And here's the corresponding non-daemon behavior (up until I killed the process):
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
Seems normal enough to me.
精彩评论