# Finalizers of multiprocessing's Pool are abruptly stopped (causing possible deadlock)

**URL:** <https://discuss.python.org/t/finalizers-of-multiprocessings-pool-are-abruptly-stopped-causing-possible-deadlock/104155>\
**Category:** Python Help\
**Created:** [October 4, 2025, 6:47am UTC](https://discuss.python.org/t/finalizers-of-multiprocessings-pool-are-abruptly-stopped-causing-possible-deadlock/104155 "2025-10-04T06:47:16Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Delgan](https://avatars.discourse-cdn.com/v4/letter/d/e8c25b/32.png) [@Delgan](https://discuss.python.org/u/Delgan)\
**Post date:** [October 4, 2025, 6:47am UTC](https://discuss.python.org/t/finalizers-of-multiprocessings-pool-are-abruptly-stopped-causing-possible-deadlock/104155/1 "2025-10-04T06:47:16Z")

</div>

Hi.

I was surprised to discover that [`multiprocessing.util.Finalize`](https://github.com/python/cpython/blob/37d16f7f620d79af7db1c00c8d638122af889bf9/Lib/multiprocessing/util.py#L249) did not seem to work for processes started by [`multiprocessing.Pool`](https://docs.python.org/3/library/multiprocessing.html#multiprocessing.pool.Pool). The finalizer is called when the pool’s context manager exits, but it isn’t given enough time to complete.

Here is a minimal reproducible example (tested with Python 3.13.5):

```python
import multiprocessing
from multiprocessing.util import Finalize
import time

class Worker:

    def setup(self, event):
        self._event = event
        self._finalizer = Finalize(self, self._finalize, exitpriority=0)

    def work(self, _):
        time.sleep(0.01)

    def _finalize(self):
        print("Finalizing...")
        time.sleep(0.1)
        print("Finalized.")
        self._event.set()

if __name__ == " __main__":
    context = multiprocessing.get_context("spawn")

    worker = Worker()
    event = context.Event()

    # It works fine with a explicit Process instance.
    process = context.Process(target=worker.setup, args=(event,))
    process.start()
    time.sleep(0.5)
    assert event.is_set() # OK

    event.clear()

    # It does not work when using a Pool.
    with context.Pool(1, initializer=worker.setup, initargs=(event,)) as pool:
        pool.map(worker.work, [None])
    time.sleep(0.5)
    assert event.is_set() # NOK

```

The “_Finalizing…_” message is printed but “_Finalized._” isn’t, and the `Event` is never set.

Worse: if the objects inherited by the pool’s process use a `multiprocessing.Lock`, it may never be released, potentially causing deadlocks. This is an issue I am encountering in one of my libraries that implements an object similar to `multiprocessing.Queue`.

I would therefore please like to know if this was a known issue, and if there was a solution to allow `Finalize` to run entirely.
