File tree Expand file tree Collapse file tree 2 files changed +40
-15
lines changed 
Misc/NEWS.d/next/Core_and_Builtins Expand file tree Collapse file tree 2 files changed +40
-15
lines changed Original file line number Diff line number Diff line change @@ -70,22 +70,46 @@ def _reentrant_call_error(self):
7070        raise  ReentrantCallError (
7171            "Reentrant call into the multiprocessing resource tracker" )
7272
73-     def  _stop (self ):
74-         with  self ._lock :
75-             # This should not happen (_stop() isn't called by a finalizer) 
76-             # but we check for it anyway. 
77-             if  self ._lock ._recursion_count () >  1 :
78-                 return  self ._reentrant_call_error ()
79-             if  self ._fd  is  None :
80-                 # not running 
81-                 return 
82- 
83-             # closing the "alive" file descriptor stops main() 
84-             os .close (self ._fd )
85-             self ._fd  =  None 
73+     def  __del__ (self ):
74+         # making sure child processess are cleaned before ResourceTracker 
75+         # gets destructed. 
76+         # see https://github.com/python/cpython/issues/88887 
77+         self ._stop (use_blocking_lock = False )
78+ 
79+     def  _stop (self , use_blocking_lock = True ):
80+         if  use_blocking_lock :
81+             with  self ._lock :
82+                 self ._stop_locked ()
83+         else :
84+             acquired  =  self ._lock .acquire (blocking = False )
85+             try :
86+                 self ._stop_locked ()
87+             finally :
88+                 if  acquired :
89+                     self ._lock .release ()
90+ 
91+     def  _stop_locked (
92+         self ,
93+         close = os .close ,
94+         waitpid = os .waitpid ,
95+         waitstatus_to_exitcode = os .waitstatus_to_exitcode ,
96+     ):
97+         # This shouldn't happen (it might when called by a finalizer) 
98+         # so we check for it anyway. 
99+         if  self ._lock ._recursion_count () >  1 :
100+             return  self ._reentrant_call_error ()
101+         if  self ._fd  is  None :
102+             # not running 
103+             return 
104+         if  self ._pid  is  None :
105+             return 
106+ 
107+         # closing the "alive" file descriptor stops main() 
108+         close (self ._fd )
109+         self ._fd  =  None 
86110
87-              os . waitpid (self ._pid , 0 )
88-              self ._pid  =  None 
111+         waitpid (self ._pid , 0 )
112+         self ._pid  =  None 
89113
90114    def  getfd (self ):
91115        self .ensure_running ()
Original file line number Diff line number Diff line change 1+ Fixing multiprocessing Resource Tracker process leaking, usually observed when running Python as PID 1.
    
 
   
 
     
   
   
          
     
  
    
     
 
    
      
     
 
     
    You can’t perform that action at this time.
  
 
    
  
     
    
      
        
     
 
       
      
     
   
 
    
    
  
 
  
 
     
    
0 commit comments