Multiprocess within flask app spinning up 2 processes

g_grillz picture g_grillz · Nov 25, 2015 · Viewed 10.7k times · Source

I am building a flask app and need some background processes to run. I decided to go with multiprocess, but it's producing two processes when running within Flask. Does anyone know why this would happen? I've tested it on OS X and Ubuntu 12.04, with the same results. Here is an example:

import time
import multiprocessing
from flask import Flask

app = Flask(__name__)
backProc = None

def testFun():
    print('Starting')
    while True:
        time.sleep(3)
        print('looping')
        time.sleep(3)
        print('3 Seconds Later')

@app.route('/')
def root():

    return 'Started a background process with PID ' + str(backProc.pid) + " is running: " + str(backProc.is_alive())

@app.route('/kill')
def kill():
    backProc.terminate()
    return 'killed: ' + str(backProc.pid)

@app.route('/kill_all')
def kill_all():
    proc = multiprocessing.active_children()
    for p in proc:
        p.terminate()
    return 'killed all'

@app.route('/active')
def active():
    proc = multiprocessing.active_children()
    arr = []
    for p in proc:
        print(p.pid)
        arr.append(p.pid)

    return str(arr)

@app.route('/start')
def start():
    global backProc
    backProc = multiprocessing.Process(target=testFun, args=(), daemon=True)
    backProc.start()
    return 'started: ' + str(backProc.pid)

if __name__ == '__main__':
    app.run(port=int("7879"))

Answer

stacklikemind picture stacklikemind · Jan 6, 2016

This is a problem with the Flask auto-reload feature, which is used during development to automatically restart the webserver when changes in code is detected, in order to serve up the new code without requiring a manual restart.

In the guide, the “app.run()” call is always placed within an “if __name__ == ‘__main__’” condition, since the reloader is set to on by default. When using multiprocessing, this condition will result in false, so you have to instead disable the Flask autoreload when using it in a function like so:

def startWebserver():
          app.run(debug=True, use_reloader=False)

Link for reference:

http://blog.davidvassallo.me/2013/10/23/nugget-post-python-flask-framework-and-multiprocessing/