setDaemon() method of threading.Thread
In simple words...
What is a Daemon thread?
- daemon threads can shut down any time in between their flow whereas non-daemon (i.e. user threads) execute completely.
- daemon threads run intermittently in the background as long as other non-daemon threads are running.
- When all of the non-daemon threads are complete, daemon threads terminate automatically (no matter whether they got fully executed or not).
- daemon threads are service providers for user threads running in the same process.
- python does not care about daemon threads to complete when in running state, NOT EVEN the finally block but python does give preference to non-daemon threads that are created by us.
- daemon threads act as services in operating systems.
- python stops the daemon threads when all user threads (in contrast to the daemon threads) are terminated. Hence daemon threads can be used to implement, for example, a monitoring functionality as the thread is stopped by the python as soon as all user threads have stopped.
In a nutshell
If you do something like this
thread = Thread(target=worker_method, daemon=True)
there is NO guarantee that worker_method
will get executed completely.
Where does this behaviour be useful?
Consider two threads t1
(parent thread) and t2
(child thread). Let t2
be daemon. Now, you want to analyze the working of t1
while it is in running state; you can write the code to do this in t2
.
Reference:
- StackOverflow - What is a daemon thread in Java?
- GeeksForGeeks - Python daemon threads
- TutotrialsPoint - Concurrency in Python - Threads
- Official Python Documentation
Here is some basic code using threading:
import Queue
import threading
def basic_worker(queue):
while True:
item = queue.get()
# do_work(item)
print(item)
queue.task_done()
def basic():
# http://docs.python.org/library/queue.html
queue = Queue.Queue()
for i in range(3):
t = threading.Thread(target=basic_worker,args=(queue,))
t.daemon = True
t.start()
for item in range(4):
queue.put(item)
queue.join() # block until all tasks are done
print('got here')
basic()
When you run it, you get
% test.py
0
1
2
3
got here
Now comment out the line:
t.daemon = True
Run it again, and you'll see that the script prints the same result, but hangs.
The main thread ends (note that got here
was printed), but the second thread never finishes.
In contrast, when t.daemon
is set to True
, the thread t
is terminated when the main thread ends.
Note that "daemon threads" has little to do with daemon processes.
It looks like people intend to use Queue to explain threading, but I think there should be a much simpler way, by using time.sleep()
, to demo a daemon thread.
Create daemon thread by setting the daemon
parameter (default as None):
from threading import Thread
import time
def worker():
time.sleep(3)
print('daemon done')
thread = Thread(target=worker, daemon=True)
thread.start()
print('main done')
Output:
main done
Process finished with exit code 0
Remove the daemon argument, like:
thread = Thread(target=worker)
Re-run and see the output:
main done
daemon done
Process finished with exit code 0
Here we already see the difference of a daemon thread:
The entire Python program can exit if only daemon thread is left.
isDaemon()
and setDaemon()
are old getter/setter API. Using constructor argument, as above, or daemon
property is recommended.
Module Queue has been renamed queue starting with Python3 to better reflect the fact that there are several queue classes (lifo, fifo, priority) in the module. so please make the changes while using this example