I would like to have my Python program run in the background as a daemon, on either Windows or Unix. I see that the python-daemon package is for Unix only; is there an alternative for cross platform? If possible, I would like to keep the code as simple as I can.
-
1I don't know the answer but I am very interested in this. – Bite code Feb 13 '10 at 15:39
-
Yeah, it's something that'd be handy to know if there's a cross-platform way of starting a Unix daemon or Windows service depending on the platform with the same/similar code. Maybe not practical, I don't know... – Nick Bolton Feb 13 '10 at 15:54
-
Can elaborate a little on what your program does? – Adam Matan Feb 13 '10 at 16:09
-
@Adam, it's probably too lengthy and off-topic to describe here ;) – Nick Bolton Feb 13 '10 at 18:07
-
Since "daemon" is just a concept, and implementations are highly platform-specific, this question doesn't make sense. Are you asking about platform-specific wrappers so your application doesn't change much? – S.Lott Feb 13 '10 at 18:56
5 Answers
In Windows it's called a "service" and you could implement it pretty easily e.g. with the win32serviceutil module, part of pywin32. Unfortunately the two "mental models" -- service vs daemon -- are very different in detail, even though they serve similar purposes, and I know of no Python facade that tries to unify them into a single framework.

- 854,459
- 170
- 1,222
- 1,395
-
Ah, so you actually recommend going down the service route in Windows; I was thinking that'd be overkill... though, I suppose Windows doesn't support background processes (only hidden windows) -- correct? – Nick Bolton Feb 13 '10 at 15:53
-
1@Nick, right -- for solidity in Windows, a service is the way to go. It's not really overkill -- it's rather simple to make a Windows service, actually, just different from making a Unix daemon (and beyond the scaffolding, which is different, the body of your code can often be essentially unchanged between the two use cases -- Unix daemon and Windows service). – Alex Martelli Feb 13 '10 at 16:20
This question is 6 years old, but I had the same problem, and the existing answers weren't cross-platform enough for my use case. Though Windows services are often used in similar ways as Unix daemons, at the end of the day they differ substantially, and "the devil's in the details". Long story short, I set out to try and find something that allows me to run the exact same application code on both Unix and Windows, while fulfilling the expectations for a well-behaved Unix daemon (which is better explained elsewhere) as best as possible on both platforms:
- Close open file descriptors (typically all of them, but some applications may need to protect some descriptors from closure)
- Change the working directory for the process to a suitable location to prevent "Directory Busy" errors
- Change the file access creation mask (
os.umask
in the Python world) - Move the application into the background and make it dissociate itself from the initiating process
- Completely divorce from the terminal, including redirecting
STDIN
,STDOUT
, andSTDERR
to different streams (oftenDEVNULL
), and prevent reacquisition of a controlling terminal - Handle signals, in particular,
SIGTERM
.
The fundamental problem with cross-platform daemonization is that Windows, as an operating system, really doesn't support the notion of a daemon: applications that start from a terminal (or in any other interactive context, including launching from Explorer, etc) will continue to run with a visible window, unless the controlling application (in this example, Python) has included a windowless GUI. Furthermore, Windows signal handling is woefully inadequate, and attempts to send signals to an independent Python process (as opposed to a subprocess, which would not survive terminal closure) will almost always result in the immediate exit of that Python process without any cleanup (no finally:
, no atexit
, no __del__
, etc).
Windows services (though a viable alternative in many cases) were basically out of the question for me: they aren't cross-platform, and they're going to require code modification. pythonw.exe
(a windowless version of Python that ships with all recent Windows Python binaries) is closer, but it still doesn't quite make the cut: in particular, it fails to improve the situation for signal handling, and you still cannot easily launch a pythonw.exe
application from the terminal and interact with it during startup (for example, to deliver dynamic startup arguments to your script, say, perhaps, a password, file path, etc), before "daemonizing".
In the end, I settled on using subprocess.Popen
with the creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
keyword to create an independent, windowless process:
import subprocess
independent_process = subprocess.Popen(
'/path/to/pythonw.exe /path/to/file.py',
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
However, that still left me with the added challenge of startup communications and signal handling. Without going into a ton of detail, for the former, my strategy was:
pickle
the important parts of the launching process' namespace- Store that in a
tempfile
- Add the path to that file in the daughter process' environment before launching
- Extract and return the namespace from the "daemonization" function
For signal handling I had to get a bit more creative. Within the "daemonized" process:
- Ignore signals in the daemon process, since, as mentioned, they all terminate the process immediately and without cleanup
- Create a new thread to manage signal handling
- That thread launches daughter signal-handling processes and waits for them to complete
- External applications send signals to the daughter signal-handling process, causing it to terminate and complete
- Those processes then use the signal number as their return code
- The signal handling thread reads the return code, and then calls either a user-defined signal handler, or uses a cytpes API to raise an appropriate exception within the Python main thread
- Rinse and repeat for new signals
That all being said, for anyone encountering this problem in the future, I've rolled a library called daemoniker that wraps both proper Unix daemonization and the above Windows strategy into a unified facade. The cross-platform API looks like this:
from daemoniker import Daemonizer
with Daemonizer() as (is_setup, daemonizer):
if is_setup:
# This code is run before daemonization.
do_things_here()
# We need to explicitly pass resources to the daemon; other variables
# may not be correct
is_parent, my_arg1, my_arg2 = daemonizer(
path_to_pid_file,
my_arg1,
my_arg2
)
if is_parent:
# Run code in the parent after daemonization
parent_only_code()
# We are now daemonized, and the parent just exited.
code_continues_here()

- 1
- 1

- 965
- 9
- 8
Two options come to mind:
Port your program into a windows service. You can probably share much of your code between the two implementations.
Does your program really use any daemon functionality? If not, you rewrite it as a simple server that runs in the background, manages communications through sockets, and perform its tasks. It will probably consume more system resources than a daemon would, but it would be quote platform independent.

- 128,757
- 147
- 397
- 562
In general the concept of a daemon is Unix specific, in particular expected behaviour with respect to file creation masks, process hierarchy, and signal handling.
You may find PEP 3143 useful wherein a proposed continuation of python-daemon is considered for Python 3.2, and many related daemonizing modules and implementations are discussed.

- 112,946
- 110
- 377
- 526
The reason it's unix only is that daemons are a Unix specific concept i.e a background process initiated by the os and usually running as a child of the root PID .
Windows has no direct equivalent of a unix daemon, the closest I can think of is a Windows Service.
There's a program called pythonservice.exe for windows . Not sure if it's supported on all versions of python though

- 5,694
- 1
- 28
- 32