How to Wait for the First Future to Complete in Python
Use concurrent.futures.wait with FIRST_COMPLETED to pause until any task finishes and inspect the remaining pending futures.
Python code
22 linesimport concurrent.futures
import time
def task(name, delay):
time.sleep(delay)
return f"{name} done"
if __name__ == "__main__":
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
futures = [
executor.submit(task, "task1", 2),
executor.submit(task, "task2", 1),
executor.submit(task, "task3", 3),
]
done, not_done = concurrent.futures.wait(
futures, return_when=concurrent.futures.FIRST_COMPLETED
)
for future in done:
print(f"Completed: {future.result()}")
print(f"Pending futures: {len(not_done)}")
Output
Completed: task2 done
Pending futures: 2
How it works
concurrent.futures.wait blocks until the condition specified by return_when is met. With FIRST_COMPLETED, it returns once at least one future is done, providing two sets: done and not_done. The done set contains the completed futures, from which you can retrieve results with future.result(). The not_done set holds the remaining futures that are still running, allowing you to process them later or cancel them if needed. This is useful for reacting to the earliest result without waiting for all tasks.
Common mistakes
- Using `as_completed` instead of `wait` when you need to handle all results, not just the first.
- Forgetting to call `future.result()` on completed futures to get the actual return value.
- Assuming `not_done` is empty; it contains all futures that haven't finished yet.
- Blocking the main thread if you forget that `wait` blocks until the condition is met.
Variations
- Use `return_when=concurrent.futures.ALL_COMPLETED` to wait for all tasks to finish.
- Use `concurrent.futures.as_completed` to iterate over futures as they complete, yielding results in completion order.
Real-world use cases
- In a web scraper, wait for the first page to load and fetch while other requests continue in the background.
- In a data pipeline, process the earliest available batch result to reduce latency before waiting for the rest.
- In a service health check, wait for the fastest ping response to determine service availability early.
Sponsored
More from Concurrency & performance
- Benchmark list.append vs deque.append in Python medium
- Build a Python Performance Profiler That Generates Readable Reports medium
- Graceful Shutdown Executor Context Manager in Python medium
- How to Build a Producer-Consumer Pattern with asyncio.Queue in Python medium
- How to Cancel an asyncio Task with Graceful Cleanup in Python medium
- How to Convert Data in Parallel with ThreadPoolExecutor in Python easy
Keep learning
Related tutorials and quizzes for this topic.