Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python multiprocessing - watch a process and restart it when fails

Consider this working code:

from multiprocessing import Process
from updaters import app1, app2

if __name__ == '__main__':

    apps = [ app1, app2]  
    for app in apps:
        instance = app()
        p = Process(target=instance.start_listener)
        p.start()
        p.join()

This works fine until one process fails (lets say some exception) - how Can I programmatically monitor the process and restart it if it fails

like image 464
alonisser Avatar asked Mar 02 '14 08:03

alonisser


People also ask

How do you restart a process in Python?

Calling the start() function on a terminated process will result in an AssertionError indicating that the process can only be started once. Instead, to restart a process in Python, you must create a new instance of the process with the same configuration and then call the start() function.

How do I check if a process is running in Python multiprocessing?

We can check if a process is alive via the multiprocessing. Process. is_alive() method.

What does multiprocessing Freeze_support () do?

freeze_support() function. Add support for when a program which uses multiprocessing has been frozen to produce a Windows executable. (Has been tested with py2exe, PyInstaller and cx_Freeze.) This function will allow a frozen program to create and start new processes via the multiprocessing.

How do you stop a process in multiprocessing in Python?

A process can be killed by calling the Process. kill() function. The call will only terminate the target process, not child processes. The method is called on the multiprocessing.


1 Answers

Poll the Process.is_alive() and if it returns False delete the process and start a new one, e.g.:

from multiprocessing import Process
from updaters import app1, app2
from time import sleep

if __name__ == '__main__':

    apps = [app1, app2]  
    processes = {}
    n = 0
    for app in apps:
        instance = app()
        p = Process(target=instance.start_listener)
        p.start()
        processes[n] = (p, app) # Keep the process and the app to monitor or restart
        n += 1

    while len(processes) > 0:
        for n in processes.keys():
            (p, a) = processes[n]
            sleep(0.5)
            if p.exitcode is None and not p.is_alive(): # Not finished and not running
                 # Do your error handling and restarting here assigning the new process to processes[n]
                 print(a, 'is gone as if never born!')
            elif p.exitcode < 0:
                print ('Process Ended with an error or a terminate', a)
                # Handle this either by restarting or delete the entry so it is removed from list as for else
            else:
                print (a, 'finished')
                p.join() # Allow tidyup
                del processes[n] # Removed finished items from the dictionary 
                # When none are left then loop will end
print ('FINISHED')
like image 125
Steve Barnes Avatar answered Sep 22 '22 15:09

Steve Barnes