freethreading

freethreading is a lightweight wrapper that provides a unified API for true parallel execution in Python. It automatically uses threading on free-threaded Python builds (where the GIL is disabled) and falls back to multiprocessing on standard ones. This enables true parallelism across Python versions while preferring the efficiency of threads over processes whenever possible.

freethreading is a drop-in replacement for most pre-existing threading and multiprocessing code. To achieve this, the module exposes only non-deprecated common functionality shared between both backends while discarding any backend-specific APIs.

Examples

from freethreading import Worker, WorkerPool, WorkerPoolExecutor, current_worker

def greet():
    print(f"Hello from {current_worker().name}!")

def square(x):
    return x * x

if __name__ == "__main__":
    # MainThread or MainProcess
    print(current_worker().name)

    # Using Worker to distribute work
    w = Worker(target=greet, name="MyWorker")
    w.start()
    w.join()

    # Using WorkerPool to distribute work
    with WorkerPool(workers=2) as pool:
        print(pool.map(square, range(5)))

    # Using WorkerPoolExecutor to distribute work
    with WorkerPoolExecutor(max_workers=2) as executor:
        future = executor.submit(greet)

Output (Standard Python):

MainProcess
Hello from MyWorker!
[0, 1, 4, 9, 16]
Hello from ForkServerProcess-4!

Output (Free-threaded Python):

MainThread
Hello from MyWorker!
[0, 1, 4, 9, 16]
Hello from ThreadPoolExecutor-0_0!

See also

threading

Threading-based parallelism.

multiprocessing

Process-based parallelism.

concurrent.futures

High-level interface for asynchronous execution.

Classes

Barrier

Synchronization barrier for coordinating Worker objects.

BoundedSemaphore

A semaphore that prevents releasing more times than acquired.

Condition

Condition variable for worker coordination.

Event

Synchronization primitive for signaling between Worker objects.

Lock

Mutual exclusion lock for worker synchronization.

Queue

FIFO queue for worker communication.

RLock

Reentrant lock for worker synchronization.

Semaphore

Counting semaphore for limiting concurrent access.

SimpleQueue

Lightweight FIFO queue for worker communication.

Worker

Thread or process for parallel execution.

WorkerPool

Pool of workers for parallel execution.

WorkerPoolExecutor

Executor that manages a pool of Worker objects.

Functions

active_children(...)

Return a list of all active workers, excluding the current one.

active_count(→ int)

Return the number of currently active workers.

current_worker(...)

Return the current worker object.

enumerate(...)

Return a list of all active worker objects, including the current one.

get_backend(→ Literal[, ])

Get the name of the active concurrency backend.

get_ident(→ int)

Return the identifier of the current worker.

Package Contents

class freethreading.Barrier(parties, action=None, timeout=None)

Synchronization barrier for coordinating Worker objects.

A barrier is used to wait for a fixed number of workers to reach a common point. Uses threading.Barrier or multiprocessing.Barrier depending on backend.

Parameters:
  • parties (int) – Number of workers required to pass the barrier.

  • action (callable, optional) – Function called by one worker when the barrier is passed.

  • timeout (float, optional) – Default timeout for wait() calls.

See also

threading.Barrier

threading implementation.

multiprocessing.Barrier

multiprocessing implementation.

Examples

from freethreading import Barrier, Worker, current_worker

def synchronized_task(checkpoint):
    print(f"'{current_worker().name}' reached checkpoint")
    checkpoint.wait()
    print(f"'{current_worker().name}' passed checkpoint")

if __name__ == "__main__":
    checkpoint = Barrier(3)
    workers = [
        Worker(name=f"Worker-{i}", target=synchronized_task, args=(checkpoint,))
        for i in range(3)
    ]
    for w in workers:
        w.start()
    for w in workers:
        w.join()

Output:

'Worker-0' reached checkpoint
'Worker-1' reached checkpoint
'Worker-2' reached checkpoint
'Worker-2' passed checkpoint
'Worker-0' passed checkpoint
'Worker-1' passed checkpoint
abort()

Put the barrier into a broken state.

reset()

Reset the barrier to its initial empty state.

wait(timeout=None)

Wait until all parties have reached the barrier.

Parameters:

timeout (float, optional) – Maximum time to wait in seconds.

Returns:

The arrival index (0 to parties-1).

Return type:

int

Raises:

threading.BrokenBarrierError – If the barrier is broken or reset.

property broken

Whether the barrier is in a broken state.

property n_waiting

The number of workers currently waiting at the barrier.

property parties

The number of workers required to trip the barrier.

class freethreading.BoundedSemaphore(value=1)

A semaphore that prevents releasing more times than acquired.

A bounded semaphore guards against excessive releases by raising an error if released more times than acquired. Uses threading.BoundedSemaphore or multiprocessing.BoundedSemaphore depending on backend.

Parameters:

value (int, default=1) – Initial value for the semaphore counter.

Examples

from freethreading import BoundedSemaphore, Worker, current_worker

def limited_resource(sem):
    with sem:
        print(f"'{current_worker().name}': in restricted section")

if __name__ == "__main__":
    sem = BoundedSemaphore(1)
    workers = [
        Worker(name=f"Worker-{i}", target=limited_resource, args=(sem,))
        for i in range(3)
    ]
    for w in workers:
        w.start()
    for w in workers:
        w.join()

Output:

'Worker-0': in restricted section
'Worker-1': in restricted section
'Worker-2': in restricted section
acquire(blocking=True, timeout=None)

Acquire the semaphore, decrementing the counter.

Parameters:
  • blocking (bool, default=True) – If True, block until the semaphore can be acquired. If False, return immediately.

  • timeout (float, optional) – Maximum time to wait in seconds when blocking. None means wait forever.

Returns:

True if acquired, False if not acquired (non-blocking or timeout).

Return type:

bool

release()

Release the semaphore, incrementing the counter.

Raises:

ValueError – If released more times than acquired.

class freethreading.Condition(lock=None)

Condition variable for worker coordination.

A condition variable allows one or more workers to wait until notified by another worker. Uses threading.Condition or multiprocessing.Condition depending on backend.

Parameters:

lock (Lock or RLock, optional) – Underlying lock to use. If not provided, a new RLock is created.

Examples

from freethreading import Condition, Queue, Worker, current_worker

def producer(condition, queue, data):
    with condition:
        queue.put(data)
        print(f"'{current_worker().name}' sent: {data}")
        condition.notify()

def consumer(condition, queue):
    with condition:
        condition.wait()
        print(f"'{current_worker().name}' received: {queue.get()}")

if __name__ == "__main__":
    condition = Condition()
    queue = Queue()
    c = Worker(name="Consumer", target=consumer, args=(condition, queue))
    p = Worker(name="Producer", target=producer, args=(condition, queue, 42))
    c.start()
    p.start()
    c.join()
    p.join()

Output:

'Producer' sent: 42
'Consumer' received: 42
acquire(blocking=True, timeout=None)

Acquire the underlying lock.

Parameters:
  • blocking (bool, default=True) – If True, block until the lock can be acquired. If False, return immediately.

  • timeout (float, optional) – Maximum time to wait in seconds when blocking. None means wait forever.

Returns:

True if acquired, False if not acquired (non-blocking or timeout).

Return type:

bool

notify(n=1)

Wake up one or more workers waiting on this condition.

Parameters:

n (int, default=1) – Number of workers to wake up.

Raises:
  • RuntimeError – When the lock is not held (threading backend).

  • AssertionError – When the lock is not held (multiprocessing backend).

notify_all()

Wake up all workers waiting on this condition.

Raises:
  • RuntimeError – When the lock is not held (threading backend).

  • AssertionError – When the lock is not held (multiprocessing backend).

release()

Release the underlying lock.

Raises:
  • RuntimeError – When the lock is not held (threading backend).

  • AssertionError – When the lock is not held (multiprocessing backend).

wait(timeout=None)

Wait until notified or a timeout occurs.

Parameters:

timeout (float, optional) – Maximum time to wait in seconds. None means wait forever.

Returns:

True if notified, False if timeout occurred.

Return type:

bool

Raises:
  • RuntimeError – When the lock is not held (threading backend).

  • AssertionError – When the lock is not held (multiprocessing backend).

wait_for(predicate, timeout=None)

Wait until a predicate becomes true.

Parameters:
  • predicate (callable) – Function that returns a boolean value.

  • timeout (float, optional) – Maximum time to wait in seconds. None means wait forever.

Returns:

The last value returned by the predicate.

Return type:

bool

Raises:
  • RuntimeError – When the lock is not held (threading backend).

  • AssertionError – When the lock is not held (multiprocessing backend).

class freethreading.Event

Synchronization primitive for signaling between Worker objects.

An event manages an internal flag that can be set or cleared. Workers can wait for the flag to be set. Uses threading.Event or multiprocessing.Event depending on backend.

See also

threading.Event

threading implementation.

multiprocessing.Event

multiprocessing implementation.

Examples

from freethreading import Event, Worker, current_worker

def wait(event):
    print(f"'{current_worker().name}': waiting for notification")
    event.wait()
    print(f"'{current_worker().name}': received notification")

def notify(event):
    event.set()
    print(f"'{current_worker().name}': sent notification")

if __name__ == "__main__":
    event = Event()
    waiter = Worker(name="Waiter", target=wait, args=(event,))
    notifier = Worker(name="Notifier", target=notify, args=(event,))
    waiter.start()
    notifier.start()
    waiter.join()
    notifier.join()

Output:

'Waiter': waiting for notification
'Notifier': sent notification
'Waiter': received notification
clear()

Reset the internal flag to false.

is_set()

Return True if and only if the internal flag is set.

Returns:

True if set, False otherwise.

Return type:

bool

set()

Set the internal flag, waking up all waiting workers.

wait(timeout=None)

Block until the internal flag is true.

Parameters:

timeout (float, optional) – Maximum time to wait in seconds. None means wait forever.

Returns:

True if the flag is set, False if a timeout occurred.

Return type:

bool

class freethreading.Lock

Mutual exclusion lock for worker synchronization.

A lock ensures only one worker enters a critical section at a time. Uses threading.Lock or multiprocessing.Lock depending on backend.

See also

threading.Lock

threading implementation.

multiprocessing.Lock

multiprocessing implementation.

Examples

from freethreading import Lock, Worker, current_worker

def critical(lock):
    with lock:
        print(f"'{current_worker().name}': acquired lock")

if __name__ == "__main__":
    lock = Lock()
    workers = [
        Worker(name="Worker-1", target=critical, args=(lock,)),
        Worker(name="Worker-2", target=critical, args=(lock,)),
        Worker(name="Worker-3", target=critical, args=(lock,)),
    ]
    for w in workers:
        w.start()
    for w in workers:
        w.join()

Output:

'Worker-1': acquired lock
'Worker-2': acquired lock
'Worker-3': acquired lock
acquire(blocking=True, timeout=None)

Acquire the lock.

Parameters:
  • blocking (bool, default=True) – If True, block until the lock can be acquired. Otherwise, return immediately.

  • timeout (float, optional) – Maximum time to wait in seconds when blocking. None means wait forever.

Returns:

True if acquired, False if not acquired (non-blocking or timeout).

Return type:

bool

locked()

Return True if the lock is currently held.

Returns:

True if locked, False otherwise.

Return type:

bool

release()

Release the lock.

Raises:
  • RuntimeError – When invoked on an unlocked lock (threading backend).

  • ValueError – When invoked on an unlocked lock (multiprocessing backend).

class freethreading.Queue(maxsize=0)

FIFO queue for worker communication.

A queue supporting task tracking with task_done() and join(). Uses queue.Queue or multiprocessing.JoinableQueue depending on backend.

Parameters:

maxsize (int, default=0) – Maximum number of items allowed in the queue. 0 means unlimited.

See also

queue.Queue

threading implementation.

multiprocessing.JoinableQueue

multiprocessing implementation.

Examples

from freethreading import Queue, Worker

def producer(queue):
    for value in range(3):
        print(f"Producing {value}")
        queue.put(value)
    queue.put(None)

def consumer(queue):
    while True:
        item = queue.get()
        if item is None:
            queue.task_done()
            break
        print(f"Consuming {item}")
        queue.task_done()

if __name__ == "__main__":
    queue = Queue()
    producer_worker = Worker(name="Producer", target=producer, args=(queue,))
    consumer_worker = Worker(name="Consumer", target=consumer, args=(queue,))
    producer_worker.start()
    consumer_worker.start()
    queue.join()
    producer_worker.join()
    consumer_worker.join()

Output:

Producing 0
Producing 1
Producing 2
Consuming 0
Consuming 1
Consuming 2
empty()

Return True if the queue is empty.

Returns:

True if empty, False otherwise.

Return type:

bool

full()

Return True if the queue is full.

Returns:

True if full, False otherwise.

Return type:

bool

get(block=True, timeout=None)

Remove and return an item from the queue.

Parameters:
  • block (bool, default=True) – If True, block until an item is available. Otherwise, return immediately.

  • timeout (float, optional) – Maximum time to wait in seconds when blocking. None means wait forever.

Returns:

The next item from the queue.

Return type:

item

Raises:

queue.Empty – If the queue is empty and non-blocking or timeout occurred.

get_nowait()

Remove and return an item without blocking.

Returns:

The next item from the queue.

Return type:

item

Raises:

queue.Empty – If queue is empty.

join()

Block until all items have been gotten and processed.

put(item, block=True, timeout=None)

Put an item into the queue.

Parameters:
  • item – Item to add to the queue.

  • block (bool, default=True) – If True, block until space is available. Otherwise, return immediately.

  • timeout (float, optional) – Maximum time to wait in seconds when blocking. None means wait forever.

Raises:

queue.Full – If the queue is full and non-blocking or timeout occurred.

put_nowait(item)

Put an item into the queue without blocking.

Parameters:

item – Item to add to the queue.

Raises:

queue.Full – If queue is full.

qsize()

Return the approximate size of the queue.

Returns:

Number of items in the queue.

Return type:

int

Raises:

NotImplementedError – On macOS, due to platform limitations (sem_getvalue not implemented).

task_done()

Indicate that a formerly enqueued task is complete.

Raises:

ValueError – If called more times than there were items placed in the queue.

class freethreading.RLock

Reentrant lock for worker synchronization.

A reentrant lock can be acquired multiple times by the same worker without blocking. The lock must be released once for each time it was acquired. Uses threading.RLock or multiprocessing.RLock depending on backend.

See also

threading.RLock

threading implementation.

multiprocessing.RLock

multiprocessing implementation.

Examples

from freethreading import RLock, Worker, current_worker

def countdown(rlock, n):
    with rlock:
        if n > 0:
            print(f"'{current_worker().name}': {n}...")
            countdown(rlock, n - 1)
        else:
            print(f"'{current_worker().name}': go!")

if __name__ == "__main__":
    rlock = RLock()
    worker = Worker(name="Worker-0", target=countdown, args=(rlock, 3))
    worker.start()
    worker.join()

Output:

'Worker-0': 3...
'Worker-0': 2...
'Worker-0': 1...
'Worker-0': go!
acquire(blocking=True, timeout=None)

Acquire the lock, incrementing the recursion level.

Parameters:
  • blocking (bool, default=True) – If True, block until the lock can be acquired. Otherwise, return immediately.

  • timeout (float, optional) – Maximum time to wait in seconds when blocking. None means wait forever.

Returns:

True if acquired, False if not acquired (non-blocking or timeout).

Return type:

bool

release()

Release the lock, decrementing the recursion level.

Raises:
  • RuntimeError – When invoked on an unlocked lock or by a worker other than the owner (threading backend).

  • AssertionError – When invoked on an unlocked lock or by a worker other than the owner (multiprocessing backend).

class freethreading.Semaphore(value=1)

Counting semaphore for limiting concurrent access.

A semaphore manages an internal counter decremented by acquire() calls and incremented by release() calls. Uses threading.Semaphore or multiprocessing.Semaphore depending on backend.

Parameters:

value (int, default=1) – Initial value for the semaphore counter.

Examples

from freethreading import Semaphore, Worker, current_worker

def limited_resource(sem):
    with sem:
        print(f"'{current_worker().name}': in restricted section")

if __name__ == "__main__":
    sem = Semaphore(1)
    workers = [
        Worker(name=f"Worker-{i}", target=limited_resource, args=(sem,))
        for i in range(3)
    ]
    for w in workers:
        w.start()
    for w in workers:
        w.join()

Output:

'Worker-0': in restricted section
'Worker-1': in restricted section
'Worker-2': in restricted section
acquire(blocking=True, timeout=None)

Acquire the semaphore, decrementing the counter.

Parameters:
  • blocking (bool, default=True) – If True, block until the semaphore can be acquired. Otherwise, return immediately.

  • timeout (float, optional) – Maximum time to wait in seconds when blocking. None means wait forever.

Returns:

True if acquired, False if not acquired (non-blocking or timeout).

Return type:

bool

release()

Release the semaphore, incrementing the counter.

class freethreading.SimpleQueue

Lightweight FIFO queue for worker communication.

A simpler queue without task tracking or size limits. Uses queue.SimpleQueue or multiprocessing.SimpleQueue depending on backend.

Examples

from freethreading import SimpleQueue, Worker

def fill_queue(queue):
    queue.put("hello")
    queue.put("world")

if __name__ == "__main__":
    queue = SimpleQueue()
    worker = Worker(target=fill_queue, args=(queue,))
    worker.start()
    print(queue.get())
    print(queue.get())
    worker.join()
    print(queue.empty())

Output:

hello
world
True
empty()

Return True if the queue is empty.

Returns:

True if empty, False otherwise.

Return type:

bool

get()

Remove and return an item from the queue.

Returns:

The next item from the queue.

Return type:

item

Notes

This method always blocks until an item is available, ensuring consistent behavior across threading and multiprocessing backends.

put(item)

Put an item into the queue.

Parameters:

item – Item to add to the queue.

Notes

This method always blocks until the item can be added, ensuring consistent behavior across threading and multiprocessing backends.

class freethreading.Worker(group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)

Thread or process for parallel execution.

Represents an activity that runs in a separate thread or process. Uses threading.Thread or multiprocessing.Process depending on backend.

Parameters:
  • group (None) – Reserved for future extension (always None).

  • target (callable, optional) – Function to be invoked by the run() method.

  • name (str, optional) – Worker name for identification.

  • args (tuple, default=()) – Positional arguments for the target function.

  • kwargs (dict, optional) – Keyword arguments for the target function.

  • daemon (bool, optional) – Whether the worker is a daemon. Daemon workers are terminated when the program exits.

Raises:

ValueError – If target, args, or kwargs are not picklable. All arguments must be picklable to ensure portability across threading and multiprocessing backends. Use module-level functions instead of lambdas or nested functions.

See also

threading.Thread

threading implementation.

multiprocessing.Process

multiprocessing implementation.

Examples

from freethreading import Worker, current_worker

def greet():
    print(f"Hello from {current_worker().name}!")

if __name__ == "__main__":
    worker = Worker(name="Worker", target=greet)
    worker.start()
    worker.join()

Output:

Hello from Worker!
is_alive()

Return whether the worker is alive.

Returns:

True if the worker is still running.

Return type:

bool

join(timeout=None)

Wait for the worker to terminate.

Parameters:

timeout (float, optional) – Maximum time to wait in seconds. None means wait forever.

Raises:
  • RuntimeError – If called before start or on the current worker (threading backend).

  • AssertionError – If called before start (multiprocessing backend).

start()

Start the worker’s activity.

Raises:
  • RuntimeError – If called more than once (threading backend).

  • AssertionError – If called more than once (multiprocessing backend).

property daemon

Whether the worker is a daemon.

property name

The worker’s name.

class freethreading.WorkerPool(workers=None, initializer=None, initargs=())

Pool of workers for parallel execution.

Provides a pool of workers that can execute tasks in parallel. Uses multiprocessing.pool.Pool or multiprocessing.pool.ThreadPool depending on backend.

Parameters:
  • workers (int, optional) – Number of workers in the pool. Defaults to the number of CPUs.

  • initializer (callable, optional) – Callable invoked on each worker at start.

  • initargs (tuple, default=()) – Arguments for initializer.

Raises:

ValueError – If initializer or initargs are not picklable. All arguments must be picklable to ensure portability across threading and multiprocessing backends. Use module-level functions instead of lambdas or nested functions.

See also

multiprocessing.pool.Pool

Process pool implementation.

multiprocessing.pool.ThreadPool

Thread pool implementation.

Examples

from freethreading import WorkerPool

def square(x):
    return x * x

if __name__ == "__main__":
    with WorkerPool(workers=4) as pool:
        print(pool.map(square, range(10)))

Output:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
apply(func, args=(), kwds=None)

Call func with arguments args and keyword arguments kwds.

Blocks until the result is ready.

Parameters:
  • func (callable) – Function to call.

  • args (tuple, default=()) – Positional arguments for func.

  • kwds (dict, optional) – Keyword arguments for func.

Returns:

Result of the function call.

Return type:

object

Raises:

ValueError – If func, args, or kwds are not picklable.

apply_async(func, args=(), kwds=None, callback=None, error_callback=None)

Asynchronous version of apply().

Parameters:
  • func (callable) – Function to call.

  • args (tuple, default=()) – Positional arguments for func.

  • kwds (dict, optional) – Keyword arguments for func.

  • callback (callable, optional) – Called with the result when ready.

  • error_callback (callable, optional) – Called with exception if call fails.

Returns:

Result object for retrieving the result.

Return type:

AsyncResult

Raises:

ValueError – If func, args, or kwds are not picklable.

close()

Prevent any more tasks from being submitted to the pool.

Once all tasks are complete, workers will exit.

imap(func, iterable, chunksize=1)

Lazier version of map().

Parameters:
  • func (callable) – Function to apply.

  • iterable (iterable) – Iterable of arguments.

  • chunksize (int, default=1) – Size of chunks for workers.

Returns:

Iterator yielding results in order.

Return type:

iterator

Raises:

ValueError – If func is not picklable.

imap_unordered(func, iterable, chunksize=1)

Like imap() but results are yielded as soon as ready.

Parameters:
  • func (callable) – Function to apply.

  • iterable (iterable) – Iterable of arguments.

  • chunksize (int, default=1) – Size of chunks for workers.

Returns:

Iterator yielding results as they complete.

Return type:

iterator

Raises:

ValueError – If func is not picklable.

join()

Wait for workers to exit.

Must call close() or terminate() before using join().

map(func, iterable, chunksize=None)

Apply func to each element in iterable.

Blocks until all results are ready.

Parameters:
  • func (callable) – Function to apply.

  • iterable (iterable) – Iterable of arguments.

  • chunksize (int, optional) – Size of chunks for workers. Larger values reduce overhead.

Returns:

List of results in order.

Return type:

list

Raises:

ValueError – If func is not picklable.

map_async(func, iterable, chunksize=None, callback=None, error_callback=None)

Asynchronous version of map().

Parameters:
  • func (callable) – Function to apply.

  • iterable (iterable) – Iterable of arguments.

  • chunksize (int, optional) – Size of chunks for workers.

  • callback (callable, optional) – Called with the result list when ready.

  • error_callback (callable, optional) – Called with exception if call fails.

Returns:

Result object for retrieving the results.

Return type:

AsyncResult

Raises:

ValueError – If func is not picklable.

starmap(func, iterable, chunksize=None)

Like map() but arguments are unpacked from iterables.

Parameters:
  • func (callable) – Function to apply.

  • iterable (iterable) – Iterable of argument tuples.

  • chunksize (int, optional) – Size of chunks for workers.

Returns:

List of results in order.

Return type:

list

Raises:

ValueError – If func is not picklable.

starmap_async(func, iterable, chunksize=None, callback=None, error_callback=None)

Asynchronous version of starmap().

Parameters:
  • func (callable) – Function to apply.

  • iterable (iterable) – Iterable of argument tuples.

  • chunksize (int, optional) – Size of chunks for workers.

  • callback (callable, optional) – Called with the result list when ready.

  • error_callback (callable, optional) – Called with exception if call fails.

Returns:

Result object for retrieving the results.

Return type:

AsyncResult

Raises:

ValueError – If func is not picklable.

terminate()

Stop workers immediately without completing outstanding work.

class freethreading.WorkerPoolExecutor(max_workers=None, initializer=None, initargs=(), **kwargs)

Executor that manages a pool of Worker objects.

Provides a high-level interface for asynchronously executing callables using a pool of workers. Uses concurrent.futures.ThreadPoolExecutor or concurrent.futures.ProcessPoolExecutor depending on backend.

Parameters:
  • max_workers (int, optional) – Maximum number of workers in the pool.

  • initializer (callable, optional) – A callable used to initialize worker threads or processes.

  • initargs (tuple, optional) – A tuple of arguments to pass to the initializer.

  • **kwargs – Additional arguments passed to the underlying executor.

See also

concurrent.futures.ThreadPoolExecutor

Thread pool executor.

concurrent.futures.ProcessPoolExecutor

Process pool executor.

Examples

from freethreading import WorkerPoolExecutor

def square(x):
    return x * x

if __name__ == "__main__":
    with WorkerPoolExecutor(max_workers=4) as executor:
        results = list(executor.map(square, range(10)))
    print(results)

Output:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
map(fn, *iterables, timeout=None, chunksize=1)

Map a function over iterables.

Parameters:
  • fn (callable) – Function to apply.

  • *iterables – Iterables to map over.

  • timeout (float, optional) – Maximum time to wait for results. None means no limit.

  • chunksize (int, default=1) – Size of chunks for workers.

Returns:

Iterator over results.

Return type:

iterator

Raises:
  • ValueError – If fn is not picklable.

  • TimeoutError – If the entire result iterator could not be generated before the timeout.

shutdown(wait=True, cancel_futures=False)

Shutdown the executor.

Parameters:
  • wait (bool, default=True) – If True, wait for pending futures to complete.

  • cancel_futures (bool, default=False) – If True, cancel pending futures.

submit(fn, *args, **kwargs)

Submit a callable to be executed.

Parameters:
  • fn (callable) – The callable to execute.

  • *args – Positional arguments for fn.

  • **kwargs – Keyword arguments for fn.

Returns:

A Future representing the execution.

Return type:

Future

Raises:

ValueError – If fn, args, or kwargs are not picklable.

freethreading.active_children() list[threading.Thread] | list[multiprocessing.process.BaseProcess]

Return a list of all active workers, excluding the current one.

Returns:

List of child thread or process objects currently alive, excluding the current worker.

Return type:

list of Thread | BaseProcess

See also

active_count

Get the count of all active workers

current_worker

Get the current worker

enumerate

Get a list of all workers

Examples

from freethreading import Worker, active_children

def busy_wait():
    while True:
        pass

if __name__ == "__main__":
    daemon = Worker(target=busy_wait, name="Daemon", daemon=True)
    daemon.start()
    print([child.name for child in active_children()])

Output:

['Daemon']
freethreading.active_count() int

Return the number of currently active workers.

Returns:

Number of currently running workers.

Return type:

int

See also

current_worker

Get the current worker

enumerate

Get a list of all workers

Notes

This counts all workers (threads or processes) that have been started but not yet finished.

Examples

from freethreading import Worker, active_count

def busy_wait():
    while True:
        pass

if __name__ == "__main__":
    daemon = Worker(target=busy_wait, daemon=True)
    daemon.start()
    print(active_count())  # Should print 2 (main worker + daemon worker)

Output:

2
freethreading.current_worker() threading.Thread | multiprocessing.process.BaseProcess

Return the current worker object.

Returns:

The underlying thread or process object corresponding to the caller.

Return type:

Thread | BaseProcess

See also

active_count

Get the count of all active workers

get_ident

Get the identifier of the current worker

Examples

from freethreading import current_worker

print(current_worker().name)

Output (Standard Python):

MainProcess

Output (Free-threaded Python):

MainThread
freethreading.enumerate() list[threading.Thread] | list[multiprocessing.process.BaseProcess]

Return a list of all active worker objects, including the current one.

Returns:

List of all underlying thread or process objects currently alive, including the current worker.

Return type:

list of Thread | BaseProcess

See also

current_worker

Get the current worker

active_children

Get a list of all workers, excluding the current one

active_count

Get the count of all active workers

Notes

Backend-specific attributes like pid (processes) or native_id (threads) are also available but not portable across backends.

Examples

from freethreading import Worker, enumerate

def busy_wait():
    while True:
        pass

if __name__ == "__main__":
    daemon = Worker(target=busy_wait, name="Daemon", daemon=True)
    daemon.start()
    print([worker.name for worker in enumerate()])

Output (Standard Python):

['Daemon', 'MainProcess']

Output (Free-threaded Python):

['MainThread', 'Daemon']
freethreading.get_backend() Literal['threading', 'multiprocessing']

Get the name of the active concurrency backend.

Returns:

‘threading’ when GIL is disabled, and ‘multiprocessing’ otherwise.

Return type:

Literal[‘threading’, ‘multiprocessing’]

freethreading.get_ident() int

Return the identifier of the current worker.

Returns:

Thread identifier or process ID of the current worker.

Return type:

int

See also

current_worker

Get the current worker