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
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.
We can check if a process is alive via the multiprocessing. Process. is_alive() method.
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.
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.
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With