You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For a child process with daemon=False creates the multiprocessing.Manager object, if it creates a thread for polling SyncManager-created Lock/Event objects, the default recycling mechanism will first release the grandchild process corresponding to the created multiprocessing.Manager object, which can interrupt the polling thread and raise Error.
After debugging, it was found that the main cause of the above exception was the invocation of BaseProcess._bootstrap after the subprocess was created and started.While releasing the program resources, that is, when the process object try to exit, the finally brach in BaseProcess._bootstrap will be taken. Which leds to calling util._exit_function in advance. The util._exit_function method will futher call the BaseManager._finalize_manager registered in the BaseManger.start method in advance, and this will trigger the exception during the runtime of thread for the accidental release of SyncManager object.
However, the multiprocessing.util module registers util._exit_function in the atexit module automatically when it is imported, which means that util._exit_function will be called naturally while subprocess exits. Consequently, can we consider the active invocation of BaseProcess._bootstrap's finally branch as unnecessary?
Of course, after learning the multiprocessing.util module, we can avoid the issue by the following:
I believe atexit module won't be triggered in forked process, as os._exit(retcode) is used to exit the program.
However, this does not seem like a resource release order issue. I think the problem is that you never appropriately end your thread.
What is the expected behavior of the code? Your thread is trying to get data from a queue unconditionally and the only way to stop it is for the process to finish. However, the process has to clean up the SyncManager - the data source of your thread - before it exits. That creates an impossible loop for your code to work properly.
The solution of your issue does not have to be as complicated as you provided. You can simply do release(mgr) at the end of your subprocess function, which is a reasonable thing to do - to stop and finish the thread before your process ends.
Summary
For a child process with daemon=False creates the multiprocessing.Manager object, if it creates a thread for polling SyncManager-created Lock/Event objects, the default recycling mechanism will first release the grandchild process corresponding to the created multiprocessing.Manager object, which can interrupt the polling thread and raise Error.
Description
The test code is as follows:
The above test code will throw the following exception:
After debugging, it was found that the main cause of the above exception was the invocation of BaseProcess._bootstrap after the subprocess was created and started.While releasing the program resources, that is, when the process object try to exit, the finally brach in BaseProcess._bootstrap will be taken. Which leds to calling util._exit_function in advance. The util._exit_function method will futher call the BaseManager._finalize_manager registered in the BaseManger.start method in advance, and this will trigger the exception during the runtime of thread for the accidental release of SyncManager object.
However, the multiprocessing.util module registers util._exit_function in the atexit module automatically when it is imported, which means that util._exit_function will be called naturally while subprocess exits. Consequently, can we consider the active invocation of BaseProcess._bootstrap's finally branch as unnecessary?
Of course, after learning the multiprocessing.util module, we can avoid the issue by the following:
The multiprocessing.util.Finalize module is not an externally visible method, so it's only a hedge.'
Environment
The text was updated successfully, but these errors were encountered: