A daemon process in Python is a background process that runs alongside your main program. Unlike regular processes, a daemon process automatically stops as soon as the main program ends. This makes daemon processes perfect for tasks that need to run quietly in the background without keeping the program alive.
For example, you might use a daemon process to handle logging, monitoring, or other side tasks that should not prevent your program from closing when its main work is done.
Creating a Daemon Process
To create a daemon process in Python, you simply set the daemon
attribute of a Process
object to True
before starting it. This tells Python that the process should run in the background and automatically stop when the main program ends.
Here’s an example:
import multiprocessing
import time
def background_task():
while True:
print("Daemon process is running...")
time.sleep(1)
if __name__ == "__main__":
p = multiprocessing.Process(target=background_task)
p.daemon = True # Set process as daemon
p.start()
time.sleep(3)
print("Main program ends, daemon process will stop automatically.")
In this code, the background_task
runs continuously in the daemon process, printing a message every second. After 3 seconds, the main program ends, and the daemon process stops automatically without needing any extra commands.
Difference Between Daemon and Non-Daemon Processes
To clearly see the difference between daemon and non-daemon processes, let’s create two separate tasks: one runs as a daemon process in the background, and the other runs as a normal (non-daemon) process.
Here’s a program with two tasks:
import multiprocessing
import time
def background_task():
while True:
print("Daemon process is running...")
time.sleep(1)
def non_daemon_task():
for i in range(5):
print("Non-daemon process working...")
time.sleep(1)
if __name__ == "__main__":
daemon_process = multiprocessing.Process(target=background_task)
daemon_process.daemon = True # Try changing this to False to see what happens
daemon_process.start()
non_daemon_process = multiprocessing.Process(target=non_daemon_task)
non_daemon_process.daemon = False
non_daemon_process.start()
non_daemon_process.join()
print("Main program ends.")
In this example, the daemon process runs endlessly in the background, printing its message every second. Meanwhile, the non-daemon process runs five times, printing its message once per second. The program waits for the non-daemon process to finish (join()
), keeping it alive.
If you change daemon_process.daemon
from True
to False
, you’ll see the program will wait for both processes to finish — which means the background task will keep running forever, and the program won’t end on its own. This shows how daemon processes stop automatically with the main program, but non-daemon processes keep it alive until they finish.
Checking If a Process Is Daemon
You can easily check whether a process is set as a daemon by reading its daemon
attribute. Here’s an example showing how to create a process, check its daemon status before and after setting it:
import multiprocessing
import time
def background_task():
while True:
print("Daemon process is running...")
time.sleep(1)
if __name__ == "__main__":
p = multiprocessing.Process(target=background_task)
print(f"Is daemon? {p.daemon}") # Check before setting daemon (default is False)
p.daemon = True # Set the process as daemon
print(f"Is daemon now? {p.daemon}")
p.start()
time.sleep(3)
print("Main program ends, daemon process will stop automatically.")
In this code, you first see the daemon
status as False
because new processes start as non-daemon by default. After setting p.daemon = True
, the status changes to True
. When you run the process, it runs in the background and will stop once the main program ends.
Daemon Processes and Resource Cleanup
Daemon processes stop immediately when the main program exits, so they don’t get a chance to clean up resources or finish their work properly. This means any code in finally
blocks or cleanup steps may not run if the process is a daemon.
Here’s an example to show this behavior:
import multiprocessing
import time
def cleanup_task():
try:
while True:
print("Daemon running cleanup task...")
time.sleep(1)
finally:
print("This may not print if process is daemon and program ends.")
if __name__ == "__main__":
p = multiprocessing.Process(target=cleanup_task)
p.daemon = True
p.start()
time.sleep(2)
print("Main program exiting.")
In this code, the finally
block may not execute because the daemon process stops abruptly when the main program ends. This demonstrates that daemon processes can be interrupted without proper cleanup.
Using Daemon Processes in Real-Life Scenarios
Daemon processes are great for background tasks like logging or monitoring that should run quietly alongside your main program without stopping it from finishing.
Here’s a simple example showing a logging process running as a daemon:
import multiprocessing
import time
def logger():
while True:
print("Logging info in background...")
time.sleep(2)
if __name__ == "__main__":
log_process = multiprocessing.Process(target=logger)
log_process.daemon = True
log_process.start()
print("Main program running main tasks...")
time.sleep(5)
print("Main program finished.")
In this example, the logger
process keeps printing log messages every two seconds. Because it’s a daemon, it runs in the background and stops automatically when the main program finishes its work.
Conclusion
In this article, you learned how to create daemon processes in Python by setting the daemon
attribute before starting a process. Daemon processes run quietly in the background and stop automatically as soon as the main program ends. They are useful for tasks like logging or monitoring that should not block your program from exiting.
Feel free to try creating your own daemon processes for background work in your Python projects.