Better concurrent.futures for modern Python 3
Project description
bettterconcurrent
This is a fork of Python 3.11.2's concurrent.futures
module, demonstrating some improvements that could be useful to merge to the standard implementation.
In short, these features are cooperative multitasking (solving the deadlock footgun) and fire-and-forget execution of task-parallel computations.
The changes currently pertain to ThreadPoolExecutor
. The architecture of ProcessPoolExecutor
is not trivially amenable to these changes and is left as-is for now.
All exported types are backwards compatible and will behave the same as concurrent.futures
, meaning that this package is a safe drop-in replacement.
Future
Futures are now aware, through a weakref, of the executor that generated them.
yield_until_done
Code running inside a function submitted to an executor can now potentially cooperatively wait for the result of a future on the same executor.
This can be done by inserting the yielding expression yield from future.yield_until_done()
.
If the executor is capable of cooperative scheduling, the current function will be paused and its continuation will be rescheduled upon completion of the future.
If the executor does not have this capability, the call will block in the same way future.result()
or future.exception()
would.
In any case, future.done()
is guaranteed to be True
after execution resumes from the yielding expression, allowing the user to access the result without further blocking.
This introduces a new pattern for cooperative multitasking.
A top-level function betterconcurrent.yield_until_done
accepts a list of futures and yields execution until all of them are done.
ThreadPoolExecutor
Cooperative Multitasking
ThreadPoolExecutor
now supports cooperative multitasking and is compatible with the yield_until_done
feature!
concurrent.futures
code that exhibits the deadlock footgun can be adjusted to use this feature and never deadlock with betterconcurrent
. Simply use yield_until_done
before blocking on the result of any futures and execution will not stall!
It should be noted that the footgun is still present in betterconcurrent
to maintain backward compatibility.
Fire-and-Forget
We enable a powerful pattern wherein functions that submit subtasks without any interest in the result can be executed until convergence.
ThreadPoolExecutor
now has a complement to shutdown
called join
.
Where shutdown
would stop the computation in its tracks and prevent it from further unfolding, join
will block until all tasks – and their subtasks – have completed, even if they continue to unfold when it is called.
Example
A search for a particular node in a tree can be parallelized by recursively spawning a subtask for each of the children. We might not care to return the value to the caller, but rather print a message or assign the result to a shared variable. See tree_search.py for an example of a parallel tree search!
To do
- Achieve full exception-safety. Some unlucky exception firings might cause undefined behavior currently.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file betterconcurrent-0.0.1.tar.gz
.
File metadata
- Download URL: betterconcurrent-0.0.1.tar.gz
- Upload date:
- Size: 31.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 98b115409f6fc92a539b21898a5784d780f7c72d7d64ed0d2f6cf63012c340ed |
|
MD5 | 1918ca6966aafcbad0d16774c1bf3c14 |
|
BLAKE2b-256 | a06003a74481f19f36c469edbf23cac39829e60e09bf41f8fa67536ecdeece11 |
File details
Details for the file betterconcurrent-0.0.1-py3-none-any.whl
.
File metadata
- Download URL: betterconcurrent-0.0.1-py3-none-any.whl
- Upload date:
- Size: 31.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 78deda83295226c551858b7f8cb6739a139d1ee81f67d3854db77296b5f6a382 |
|
MD5 | 030b88760de77985b2fcfc2518571887 |
|
BLAKE2b-256 | dee5d5ba6c457e712b79f43a3384f37ee17be809aab5dbc297999af161b1acf0 |