Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python Future cancellation: queued work versus running work

Last updated: 1 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

Future.cancel() can prevent a queued executor call from starting, but cannot interrupt a callable that is already running.

Download Python source kit

Operation contract

A single-worker pool is occupied with one ledger export. A second export remains queued, so cancel() can remove it before a worker begins. Once a callable is running, cancel() returns False; the callable needs its own cooperative stop rule. Worker count limits parallel execution, not retained queue memory.

Failure and ownership boundary

Two events make the transition observable. The first worker signals that it started, then waits until the caller releases it. In application code, release that wait in a finally block so an assertion or shutdown failure cannot strand the pool. A timeout on future.result() stops only the caller's wait. It does not stop the worker.

Working program

python
from concurrent.futures import ThreadPoolExecutor
from threading import Event

started = Event()
release = Event()

def export_ledger():
    started.set()
    release.wait()
    return "ledger-ready"

with ThreadPoolExecutor(max_workers=1) as workers:
    running = workers.submit(export_ledger)
    started.wait()
    pending = workers.submit(lambda: "second-export")
    print("pending cancelled:", pending.cancel())
    release.set()
    print("running result:", running.result())
    print("second cancelled:", pending.cancelled())

Output

Output
pending cancelled: True
running result: ledger-ready
second cancelled: True

Costs and limits

Every queued Future retains a callable and its arguments. Large payloads need admission control before submission.

Common Mistakes

  • A result timeout does not stop a running callable.
  • cancel() cannot forcibly interrupt a worker in progress.
  • A small worker count does not imply a small queue.

Connected lessons

Python thread pools: collect results and observe worker failures, Python Condition: wait for protected state, not for a notification count, Python asyncio Semaphore: bound active work, not queued tasks.

python
future-cancel-before-start
Storage details