I have some subprocesses (using multiprocessing) and when they stop, each of them need do some final work. Something like the following, which did not work though...
import multiprocessing
import atexit
def final():
print "final work"
def worker():
print 'Doing some work'
atexit.register(final)
if __name__ == '__main__':
p = multiprocessing.Process(target=worker)
p.start()
p.join()
So how could I do this?
atexit is a module in python which contains two functions register() and unregister(). The main role of this module is to perform clean up upon interpreter termination. Functions that are registered are automatically executed upon interpreter termination.
The atexit module defines functions to register and unregister cleanup functions. Functions thus registered are automatically executed upon normal interpreter termination.
In this example, at first we import the Process class then initiate Process object with the display() function. Then process is started with start() method and then complete the process with the join() method. We can also pass arguments to the function using args keyword.
multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads.
The atexit module in the standard distribution of Python has two functions – register () and unregister (). Both functions take some existing function as an argument. Registered functions are executed automatically when the interpreter session is terminated normally.
atexit is a module in python which contains two functions register () and unregister (). The main role of this module is to perform clean up upon interpreter termination. Functions that are registered are automatically executed upon interpreter termination.
Even though function registered more than once unregister () stops the function from execution at the time of the interpreter termination. Python is a mighty and useful programming language. Because of its open-source nature, we have a vast, number of libraries available for making our work simple and fast.
Whenever a program is killed by a signal not handled by Python, when os.exit () is called, or Python fatal internal error is detected, the functions registered via this module are not executed. register (): Register function takes a function as an argument that is to be executed at interpreter termination.
Processes started via multiprocessing do not exit normally and atexit
functions get never called. You have to run cleanup stuff manually via a try/finally block, for example:
def worker():
try:
print('Doing some work')
finally:
final()
Or, if you really want to use atexit
(see below for the drawbacks):
def worker():
try:
print('Doing some work')
finally:
atexit._run_exitfuncs()
Why don't subprocesses exit normally?
Technically, because they quit via os._exit()
, skipping any cleanup job (including atexit
functions, __del__()
and weakref finalizers).
The reason behind this decision is that cleanup stuff risks being executed at the wrong time, in the wrong process. Most of the code that uses atexit
(or other mechanisms) expects the code to be executed only once and only when the main interpreter exits (for example, one may use atexit
to remove a temporary directory). By executing atexit
functions every time a subprocess quits, you break this expectation and bad things may happen.
So, even though you can run atexit
functions via atexit._run_exitfuncs()
, avoid doing so, both because the function is undocumented and because you may not be the only user of atexit
(other third party libraries may use it, and you may introduce bugs in their code).
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