ActiveState Code

Recipe 52216: (untitled)


Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import sys 
import os  
if os.fork()==0:
    os.setsid()
    sys.stdout=open("/dev/null", 'w')
    sys.stdin=open("/dev/null", 'r')
    while(1):
        # Daemon's main code goes here                 
        pass

sys.exit(0)

Comments

  1. 1. At 12:23 p.m. on 6 nov 2001, Wm Annis said:

    Typo in the code: The parens are missing on the os.setsid() call.

  2. 2. At 7:06 a.m. on 12 jun 2002, Michael Kent said:

    Attack of the zombie processes... My understanding of *NIX daemon processes is that, to avoid creating a 'zombie' process, you must use the standard 'double-fork' technique -- you must fork an intermidiate child process, that then forks the desired child process. Comments?

  3. 3. At 3:13 a.m. on 14 jul 2002, Tobias Klausmann said:

    no Zombie army... I just used:

    #!/usr/bin/python
    import sys
    import os,time
    
    if os.fork()==0:
        os.setsid()
        sys.stdout=open("/dev/null", 'w')
        sys.stdin=open("/dev/null", 'r')
        time.sleep(20)
    
    sys.exit(0)
    

    And it resulted in no Zombie. Therefore, I guess, things work out right. It might be another issue if you do Shell Magick when starting the program, so the double fork could be added, just to be safe:

    #!/usr/bin/python
    
    import sys
    import os,time
    if os.fork()==0:
        os.setsid()
        sys.stdout=open("/dev/null", 'w')
        sys.stdin=open("/dev/null", 'r')
        if os.fork()==0:
            time.sleep(20) # or whatever your daemon does
    
    sys.exit(0)
    
  4. 4. At 3:06 a.m. on 5 aug 2002, Andy Gimblett said:

    More complete implementation of forking a daemon. A more definitive/complete answer to the question "How do I get my program to act like a daemon?" is given by the following Unix Programming FAQ entry:

    http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16

    ...which is fairly completely implemented by the following python cookbook entry (and its comments):

    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012

  5. 5. At 5:16 p.m. on 27 aug 2002, Noah Spurrier said:

    You need to double fork... A daemon is different than a background process. A background process is attached to a process group of a controlling terminal (your login shell). If your controlling terminal dies then you background jobs also die. I strongly suspect that your original code will die when you exit your login shell.

    The reason you need to double fork is to disconnect your new process group from the parent process controlling terminal. Failing to do this does not cause a zombie. Instead, failing to do this causes the child process to be sent copies of the signals sent to the parent. That means when the parent login shell dies (HUP signal) or gets killed (KILL signal) those signals will be broadcast to the children.

    The following code demonstrates a daemon in Python. When you start this up and a file ('/tmp/daemon.log') will slowly get filled with integers (once per second). You can logout, kill your shell, or whatever and the daemon will still run. It will not appear in the process list unless you do 'ps -x' to list processes without controlling terminals.

    Note that you have to have correct permissions to do this. Some systems will not allow you to create a daemon. Some UNIXes have other mechanisms to do this. I'm pretty sure that this is portable.

    I'm no authority. This is from memory. I may be wrong,

    Yours,

    Noah

    #!/usr/bin/env python
    '''Daemon example'''
    
    import os, sys, time
    
    def main ():
        '''This is the main function run by the daemon.
        '''
        fout = open ('/tmp/daemon.log', 'a')
        fout.write ('daemon started with pid %d\n' % os.getpid())
        c = 0
        while 1:
            fout.write ('Count: %d\n' % c)
            fout.flush()
            c = c + 1
            time.sleep(1)
    
    if __name__ == '__main__':
        pid = os.fork ()
        if pid == 0: # if pid is child...
            os.setsid() # Create new session and sets process group.
            pid = os.fork () # Will have INIT (pid 1) as parent process...
            if pid == 0: # if pid is child...
                main ()
    
  6. 6. At 3:08 p.m. on 4 oct 2002, Keith Dart said:

    setpgrp vs. double fork. I believe that calling setpgrp() in your forked daemon obviates the need for a second fork. That is what I have always done and it seems to work fine.

  7. 7. At 2:29 p.m. on 16 nov 2002, Michael Babcock said:

    Consider doing these only optionally. I hate it personally when programs insist on behaving like this normally; I use supervise to monitor all my daemon processes and it works wonderfully; no extra code in the daemons at all and good notification (and auto-restarting) of daemon death.

  8. 8. At 11:10 a.m. on 8 jul 2007, Richard Moore said:

    Simplified backgrounding... Could you not simply use the following to background the current process?

    if not (os.fork() == 0 and os.fork() == 0): sys.exit(0)
    

    Thanks,

    RicMoo

  9. 9. At 12:35 p.m. on 29 jul 2008, ben w said:

    Here's the same code in a slightly different form:

    def become_daemon():
        pid = os.fork ()
        if pid != 0: # if pid is not child...
            sys.exit(0)
    
        os.setsid() # Create new session and sets process group.
        pid = os.fork () # Will have INIT (pid 1) as parent process...
        if pid != 0: # if pid is not child...
            sys.exit(0)
    

    Then, at the beginning of my script I can do:

    become_daemon()
    
    # do whatever
    

Sign in to comment