6

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()
3
  • 1
    The python-daemon library is a handy package to create daemons easily, by the way. Commented Mar 16, 2016 at 10:26
  • Agreed, multiprocessing isn't the right tool to implement a daemon. Generally you want to use the double-forking idiom for a Unix daemon, so just use the library Carpetsmoker linked. Commented Mar 16, 2016 at 10:28
  • @Carpetsmoker Thanks, will try :) Commented Mar 16, 2016 at 11:38

2 Answers 2

6

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()
Sign up to request clarification or add additional context in comments.

2 Comments

Documentation for join(). "the method blocks until the process whose join() method is called terminates."
Yeah, but the result is the same :P
2

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())

3 Comments

I undestood why to do os.setsid() after reading this. But why to do (1) os.chdir('/') (2) os.umask(0) and (3) that file descriptor stuff? What if I dont do some of them? Also can we do similar with python multiprocessing.Process?
@Mahesha999 1. We need to change the working directory for a safe place. For example, directory from which the application will be run may be unmount in the future. The root directory is the best way. 2. umask(0) gives full access (-rw-rw-rw-) to the files which will created by the daemon. 3. We close file descriptors as the daemon disconnected from the terminal and shouldn't send any data via pipes. For that we open /dev/null and change the daemon's file discriptors to the /dev/null descriptors.
@Mahesha999 We do all these things as these are rules of creating daemon process: netzmafia.de/skripten/unix/linux-daemon-howto.html I showed the way how to transform an application to the daemon via one function. This method only depends on sys and os modules. Also exist other ways to create unix daemon in python, it's only one of them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.