2 min read

Python Concurrent Futures Module

The concurrent.futures module provides a high-level interface for asynchronously executing callables. It abstracts the execution of tasks in threads or processes using ThreadPoolExecutor and ProcessPoolExecutor.

Importing the Module

import concurrent.futures

Executor Objects

ThreadPoolExecutor

ThreadPoolExecutor is an Executor subclass that uses a pool of threads to execute calls asynchronously. It is suitable for I/O-bound tasks.

import concurrent.futures
import time

def task(n):
    print(f"Processing {n}")
    time.sleep(1)
    return n * n

with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    future = executor.submit(task, 5)
    print(f"Result: {future.result()}")

ProcessPoolExecutor

ProcessPoolExecutor is an Executor subclass that uses a pool of processes to execute calls asynchronously. It uses the multiprocessing module, which allows it to side-step the Global Interpreter Lock (GIL) but also means that only picklable objects can be executed and returned. It is suitable for CPU-bound tasks.

import concurrent.futures

def square(n):
    return n * n

if __name__ == '__main__':
    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = executor.map(square, [1, 2, 3, 4, 5])
        for result in results:
            print(result)

Submitting Tasks

submit()

The submit() method schedules the callable, fn, to be executed as fn(*args, **kwargs) and returns a Future object representing the execution of the callable.

with concurrent.futures.ThreadPoolExecutor() as executor:
    future1 = executor.submit(pow, 323, 1235)
    future2 = executor.submit(pow, 323, 1235)

    print(future1.result())
    print(future2.result())

map()

The map() method is similar to the built-in map() function. It runs the function asynchronously on the iterables.

with concurrent.futures.ThreadPoolExecutor() as executor:
    for result in executor.map(lambda x: x**2, range(10)):
        print(result)

Future Objects

A Future instance represents the encapsulation of the asynchronous execution of a callable.

  • result(timeout=None): Return the value returned by the call.
  • cancel(): Attempt to cancel the call.
  • done(): Return True if the call was successfully cancelled or finished running.
  • add_done_callback(fn): Attaches the callable fn to the future.

as_completed()

The as_completed() function returns an iterator over the Future instances (that are possibly created by different Executor instances) that yields futures as they complete (finished or cancelled).

programming/python/python