Daemon processes in Python To execute the process in the background, we need to set the daemonic flag to true. The daemon process will continue to run as long as the main process is executing and it will terminate after finishing its execution or when the main program would be killed.
daemon-This property that is set on a python thread object makes a thread daemonic. A daemon thread does not block the main thread from exiting and continues to run in the background. In the below example, the print statements from the daemon thread will not printed to the console as the main thread exits.
Current solution
A reference implementation of PEP 3143 (Standard daemon process library) is now available as python-daemon.
Historical answer
Sander Marechal's code sample is superior to the original, which was originally posted in 2004. I once contributed a daemonizer for Pyro, but would probably use Sander's code if I had to do it over.
There are many fiddly things to take care of when becoming a well-behaved daemon process:
prevent core dumps (many daemons run as root, and core dumps can contain sensitive information)
behave correctly inside a chroot
gaol
set UID, GID, working directory, umask, and other process parameters appropriately for the use case
relinquish elevated suid
, sgid
privileges
close all open file descriptors, with exclusions depending on the use case
behave correctly if started inside an already-detached context, such as init
, inetd
, etc.
set up signal handlers for sensible daemon behaviour, but also with specific handlers determined by the use case
redirect the standard streams stdin
, stdout
, stderr
since a daemon process no longer has a controlling terminal
handle a PID file as a cooperative advisory lock, which is a whole can of worms in itself with many contradictory but valid ways to behave
allow proper cleanup when the process is terminated
actually become a daemon process without leading to zombies
Some of these are standard, as described in canonical Unix literature (Advanced Programming in the UNIX Environment, by the late W. Richard Stevens, Addison-Wesley, 1992). Others, such as stream redirection and PID file handling, are conventional behaviour most daemon users would expect but that are less standardised.
All of these are covered by the PEP 3143 “Standard daemon process library” specification. The python-daemon reference implementation works on Python 2.7 or later, and Python 3.2 or later.
Here's my basic 'Howdy World' Python daemon that I start with, when I'm developing a new daemon application.
#!/usr/bin/python
import time
from daemon import runner
class App():
def __init__(self):
self.stdin_path = '/dev/null'
self.stdout_path = '/dev/tty'
self.stderr_path = '/dev/tty'
self.pidfile_path = '/tmp/foo.pid'
self.pidfile_timeout = 5
def run(self):
while True:
print("Howdy! Gig'em! Whoop!")
time.sleep(10)
app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()
Note that you'll need the python-daemon
library. You can install it by:
pip install python-daemon
Then just start it with ./howdy.py start
, and stop it with ./howdy.py stop
.
Note the python-daemon package which solves a lot of problems behind daemons out of the box.
Among other features it enables to (from Debian package description):
An alternative -- create a normal, non-daemonized Python program then externally daemonize it using supervisord. This can save a lot of headaches, and is *nix- and language-portable.
Probably not a direct answer to the question, but systemd can be used to run your application as a daemon. Here is an example:
[Unit]
Description=Python daemon
After=syslog.target
After=network.target
[Service]
Type=simple
User=<run as user>
Group=<run as group group>
ExecStart=/usr/bin/python <python script home>/script.py
# Give the script some time to startup
TimeoutSec=300
[Install]
WantedBy=multi-user.target
I prefer this method because a lot of the work is done for you, and then your daemon script behaves similarly to the rest of your system.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With