In Python, daemon threads are background threads that run without blocking the main program from exiting.
They are often used for tasks that should continue running in the background but do not need to prevent the program from terminating.
If the main program exits, daemon threads will also terminate, even if they have not completed their execution.
In this tutorial, you will learn:
What are daemon threads?
How to create and use daemon threads
Difference between regular and daemon threads
Use cases for daemon threads
Practical examples of daemon threads
1. What Are Daemon Threads?
A daemon thread is a thread that runs in the background and does not prevent the program from exiting. Daemon threads typically run non-essential or background tasks, such as logging, monitoring, or periodic cleanups.
Once the main program exits, daemon threads are immediately terminated without finishing their tasks.
The opposite of a daemon thread is a non-daemon (or regular) thread, which will continue to run until it completes its task and will prevent the program from exiting until all non-daemon threads finish.
2. How to Create and Use Daemon Threads
You can create a daemon thread by setting the daemon attribute to True on the Thread object. This ensures that the thread runs as a daemon and will not block the program from exiting.
Example 1: Creating a Daemon Thread
import threading import time def background_task(): while True: print("Background task is running...") time.sleep(1) # Create a thread thread = threading.Thread(target=background_task) # Set the thread as a daemon thread thread.daemon = True # Start the thread thread.start() # Main program sleeps for 3 seconds and then exits time.sleep(3) print("Main program exits")
Output:
Background task is running... Background task is running... Background task is running... Main program exits
In this example:
The background_task() function runs indefinitely in a loop.
Since the thread is a daemon thread, it will terminate when the main program exits after 3 seconds, even though the task is still running.
3. Difference Between Regular and Daemon Threads
The main difference between regular and daemon threads is how they interact with the main program:
Regular threads: The program will not terminate until all regular (non-daemon) threads have finished executing.
Daemon threads: These threads run in the background and are abruptly terminated when the main program exits.
Example 2: Regular vs. Daemon Thread
Let’s compare the behavior of regular and daemon threads when the main program exits.
import threading import time def long_running_task(): for i in range(5): print(f"Task running: {i}") time.sleep(1) # Regular thread (non-daemon) regular_thread = threading.Thread(target=long_running_task) # Daemon thread daemon_thread = threading.Thread(target=long_running_task) daemon_thread.daemon = True # Make this thread a daemon # Start both threads regular_thread.start() daemon_thread.start() # Main program exits after 2 seconds time.sleep(2) print("Main program exits")
Output:
Task running: 0 Task running: 0 Task running: 1 Task running: 1 Main program exits Task running: 2 Task running: 3 Task running: 4
In this example:
The regular thread continues running even after the main program prints “Main program exits” and finishes its entire task.
The daemon thread is terminated as soon as the main program exits, so it doesn't print anything after “Main program exits.”
4. Use Cases for Daemon Threads
Daemon threads are commonly used for tasks that are non-critical to the program’s execution. These tasks can run in the background and do not need to block the program’s termination. Some common use cases include:
Logging: A daemon thread can write logs to a file or send them to a remote server while the main program runs.
Monitoring: Daemon threads can monitor resources, such as memory usage or CPU utilization, without affecting the main program.
Background Cleanup: Daemon threads can be used for periodic cleanup tasks that don't need to complete before the program exits.
Maintenance Tasks: Daemon threads can run maintenance tasks, such as updating caches or refreshing configurations.
5. Practical Examples of Daemon Threads
Example 3: Daemon Thread for Logging
Let’s implement a simple logging daemon thread that logs messages in the background while the main program performs other tasks.
import threading import time def log_messages(): while True: print("Logging message...") time.sleep(2) # Create a daemon thread for logging log_thread = threading.Thread(target=log_messages) log_thread.daemon = True # Set the thread as a daemon log_thread.start() # Simulate main program activity for i in range(3): print(f"Main program is working... {i}") time.sleep(1) print("Main program exits")
Output:
Logging message... Main program is working... 0 Main program is working... 1 Logging message... Main program is working... 2 Main program exits
In this example, the logging thread runs in the background but gets terminated when the main program finishes after 3 iterations.
Example 4: Daemon Thread for Periodic Monitoring
Let’s create a daemon thread that monitors memory usage every 2 seconds while the main program runs.
import threading import time import psutil # You need to install psutil for this example (pip install psutil) def monitor_memory(): while True: memory = psutil.virtual_memory() print(f"Memory Usage: {memory.percent}%") time.sleep(2) # Create a daemon thread for monitoring memory monitor_thread = threading.Thread(target=monitor_memory) monitor_thread.daemon = True # Set the thread as a daemon monitor_thread.start() # Simulate main program activity for i in range(5): print(f"Main program is working... {i}") time.sleep(1) print("Main program exits")
Output:
Memory Usage: 45.7% Main program is working... 0 Main program is working... 1 Memory Usage: 45.7% Main program is working... 2 Main program is working... 3 Memory Usage: 45.7% Main program is working... 4 Main program exits
In this example, the monitor_memory function prints memory usage every 2 seconds in the background.
However, since the thread is a daemon thread, it is terminated when the main program exits.
Example 5: Daemon Thread for Periodic File Cleanup
Here’s an example of a daemon thread that performs background cleanup by deleting temporary files every 5 seconds.
import threading import time import os def cleanup_temp_files(): while True: # Simulate temp file cleanup print("Cleaning up temporary files...") time.sleep(5) # Create a daemon thread for background cleanup cleanup_thread = threading.Thread(target=cleanup_temp_files) cleanup_thread.daemon = True # Set the thread as a daemon cleanup_thread.start() # Main program performs other tasks for i in range(3): print(f"Main program task {i}...") time.sleep(2) print("Main program exits")
Output:
Cleaning up temporary files... Main program task 0... Main program task 1... Main program task 2... Main program exits
In this case, the cleanup task is running in the background, but as soon as the main program exits, the daemon thread is stopped, even though it might not have finished its task.
6. Important Notes on Daemon Threads
Premature Termination: Daemon threads are terminated immediately when the main program exits, even if they are in the middle of an operation.
This can lead to incomplete tasks, especially for I/O-bound operations like file writing or network requests.
Non-Critical Tasks: Daemon threads are best suited for non-critical tasks that don't require completion, like logging, monitoring, or background cleanup.
Avoid Daemon Threads for Important Tasks: If you have a task that must be completed (such as saving critical data), it should run on a non-daemon thread to ensure that it finishes before the program exits.
Conclusion
Daemon threads are a useful tool in Python for running background tasks without blocking the main program. Here’s a summary of what you’ve learned:
Daemon threads are background threads that terminate when the main program exits.
You can create a daemon thread by setting daemon=True on the Thread object.
Regular threads block the program from exiting, whereas daemon threads do not.
Daemon threads are useful for non-critical tasks like logging, monitoring, or background cleanup.
By understanding how daemon threads work, you can efficiently manage background tasks in your Python programs!