Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a daemon process in Python?

I am writing a small program which has a heartbeat process and an echo process. I implemented this with a multiprocessing library, but it doesn't seem to work.

from multiprocessing import Process
import os
import time

def ticking():
    while True:
        time.sleep(1)
        print 'ticking'

def echo():
    while True:
        a = raw_input('please type something')
        print 'echo: ' + a

if __name__ == '__main__':
    p = Process(target=ticking, args=())
    p.start()
    p.join()

    p = Process(target=echo, args=())
    p.start()
    p.join()
like image 407
alvinzoo Avatar asked Mar 16 '16 10:03

alvinzoo


2 Answers

You create a process that will run forever and join() to it. The second process will never get created, because the join() will stall your main process forever.

If this is how you want to proceed, then you should for example first create both processes and then join them:

if __name__ == '__main__':
    p1 = Process(target=ticking, args=())
    p1.start()

    p2 = Process(target=echo, args=())
    p2.start()

    p1.join()
    p2.join()
like image 103
Ilja Everilä Avatar answered Oct 29 '22 12:10

Ilja Everilä


For create a daemon you can use this function:

def daemonize():
    """UNIX double fork mechanism."""
    try:
        pid = os.fork()
        if pid > 0:
            # exit first parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #1 failed: {0}\n'.format(err))
        sys.exit(1)
    # decouple from parent environment
    os.chdir('/')
    os.setsid()
    os.umask(0)
    # do second fork
    try:
        pid = os.fork()
        if pid > 0:
            # exit from second parent
            sys.exit(0)
    except OSError as err:
        sys.stderr.write('_Fork #2 failed: {0}\n'.format(err))
        sys.exit(1)
    # redirect standard file descriptors
    sys.stdout.flush()
    sys.stderr.flush()
    si = open(os.devnull, 'r')
    so = open(os.devnull, 'w')
    se = open(os.devnull, 'w')
    os.dup2(si.fileno(), sys.stdin.fileno())
    os.dup2(so.fileno(), sys.stdout.fileno())
    os.dup2(se.fileno(), sys.stderr.fileno())
like image 36
Ivan Kolesnikov Avatar answered Oct 29 '22 12:10

Ivan Kolesnikov