Shutdown the executor and clean up resources. Parameters ---------- wait : bool If True, wait for pending work to complete. Note ---- DEADLOCK WARNING: This method can deadlock when called during garbage collection due to exceptio
(self, wait=True)
| 385 | self.shutdown(wait=True) |
| 386 | |
| 387 | def shutdown(self, wait=True): |
| 388 | """Shutdown the executor and clean up resources. |
| 389 | |
| 390 | Parameters |
| 391 | ---------- |
| 392 | wait : bool |
| 393 | If True, wait for pending work to complete. |
| 394 | |
| 395 | Note |
| 396 | ---- |
| 397 | DEADLOCK WARNING: This method can deadlock when called during garbage |
| 398 | collection due to exception reference cycles. When exceptions occur, |
| 399 | Python creates reference cycles that delay garbage collection. The |
| 400 | deadlock happens when: exception creates reference cycle → new pool |
| 401 | creates worker → GC cleans old pool → old pool's __del__ calls shutdown() |
| 402 | which tries to acquire locks again. |
| 403 | """ |
| 404 | self._lock.acquire() |
| 405 | for worker in self._worker_map.values(): |
| 406 | try: |
| 407 | worker.kill() |
| 408 | except ImportError: |
| 409 | pass |
| 410 | self._lock.release() |
| 411 | self._threadpool.shutdown(wait=wait) |
| 412 | self._shutdown = True |
| 413 | |
| 414 | def _worker_run(self, fn, args, kwargs): |
| 415 | """Internal thread runner.""" |