-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
gh-124694: Add concurrent.futures.InterpreterPoolExecutor #124548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 35 commits
5c69d38
01789be
6def4be
84993a5
c540cf0
45d584d
c90c016
1cb4657
4dc0989
57b2db6
75e11d2
69c2b8e
f03c314
4806d9f
efc0395
a29aee3
8bab457
cd29914
0287f3b
80cd7b1
f8d4273
3a8bfce
af6c27a
8c0a405
1ae7ca2
d24e85d
05a03ad
f150931
97d0292
baf0504
5c3a327
a2032a8
54119b8
744dca7
f61d62d
ee65bb2
a7f5c50
b148e09
e365ae7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -15,9 +15,10 @@ The :mod:`concurrent.futures` module provides a high-level interface for | |||||||||||||||||||||
asynchronously executing callables. | ||||||||||||||||||||||
|
||||||||||||||||||||||
The asynchronous execution can be performed with threads, using | ||||||||||||||||||||||
:class:`ThreadPoolExecutor`, or separate processes, using | ||||||||||||||||||||||
:class:`ProcessPoolExecutor`. Both implement the same interface, which is | ||||||||||||||||||||||
defined by the abstract :class:`Executor` class. | ||||||||||||||||||||||
:class:`ThreadPoolExecutor` or :class:`InterpreterPoolExecutor`, | ||||||||||||||||||||||
or separate processes, using :class:`ProcessPoolExecutor`. | ||||||||||||||||||||||
Each implements the same interface, which is defined | ||||||||||||||||||||||
by the abstract :class:`Executor` class. | ||||||||||||||||||||||
|
||||||||||||||||||||||
.. include:: ../includes/wasm-notavail.rst | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
@@ -63,7 +64,8 @@ Executor Objects | |||||||||||||||||||||
setting *chunksize* to a positive integer. For very long iterables, | ||||||||||||||||||||||
using a large value for *chunksize* can significantly improve | ||||||||||||||||||||||
performance compared to the default size of 1. With | ||||||||||||||||||||||
:class:`ThreadPoolExecutor`, *chunksize* has no effect. | ||||||||||||||||||||||
:class:`ThreadPoolExecutor` and :class:`InterpreterPoolExecutor`, | ||||||||||||||||||||||
*chunksize* has no effect. | ||||||||||||||||||||||
|
||||||||||||||||||||||
.. versionchanged:: 3.5 | ||||||||||||||||||||||
Added the *chunksize* argument. | ||||||||||||||||||||||
|
@@ -227,6 +229,59 @@ ThreadPoolExecutor Example | |||||||||||||||||||||
print('%r page is %d bytes' % (url, len(data))) | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
||||||||||||||||||||||
InterpreterPoolExecutor | ||||||||||||||||||||||
----------------------- | ||||||||||||||||||||||
|
||||||||||||||||||||||
The :class:`InterpreterPoolExecutor` class, a :class:`ThreadPoolExecutor` | ||||||||||||||||||||||
subclass, uses a pool of isolated interpreters to execute calls | ||||||||||||||||||||||
asynchronously. Since each interpreter is isolated from the others, | ||||||||||||||||||||||
side-stepping the :term:`Global Interpreter Lock <global interpreter lock>` , | ||||||||||||||||||||||
multiple cores can be used. Since Interpreters do not share | ||||||||||||||||||||||
objects between them, in most cases, only picklable | ||||||||||||||||||||||
objects can be executed and returned. | ||||||||||||||||||||||
|
||||||||||||||||||||||
.. class:: InterpreterPoolExecutor(max_workers=None, thread_name_prefix='', initializer=None, initargs=(), shared=None) | ||||||||||||||||||||||
|
||||||||||||||||||||||
A :class:`ThreadPoolExecutor` subclass that executes calls asynchronously | ||||||||||||||||||||||
using a pool of at most *max_workers* threads. Each thread runs | ||||||||||||||||||||||
tasks in its own interpreter. | ||||||||||||||||||||||
|
||||||||||||||||||||||
*initializer* may be a callable and *initargs* a tuple of arguments, | ||||||||||||||||||||||
just like with :class:`ThreadPoolExecutor`. However, they are pickled | ||||||||||||||||||||||
like with :class:`ProcessPoolExecutor`. Likewise, functions (and | ||||||||||||||||||||||
arguments) passed to :meth:`~Executor.submit` are pickled. | ||||||||||||||||||||||
|
||||||||||||||||||||||
.. note:: | ||||||||||||||||||||||
functions defined in the ``__main__`` module cannot be pickled | ||||||||||||||||||||||
and thus cannot be used. | ||||||||||||||||||||||
|
||||||||||||||||||||||
*shared* is an optional dict of objects shared by all interpreters | ||||||||||||||||||||||
in the pool. The items are added to each interpreter's ``__main__`` | ||||||||||||||||||||||
module. Not all objects are shareable. Those that are include | ||||||||||||||||||||||
the builtin singletons, :class:`str` and :class:`bytes`, | ||||||||||||||||||||||
and :class:`memoryview`. See :pep:`734` for more info. | ||||||||||||||||||||||
|
*shared* is an optional dict of objects shared by all interpreters | |
in the pool. The items are added to each interpreter's ``__main__`` | |
module. Not all objects are shareable. Those that are include | |
the builtin singletons, :class:`str` and :class:`bytes`, | |
and :class:`memoryview`. See :pep:`734` for more info. | |
*shared* is an optional dict of objects shared by all isolated interpreters | |
in the pool. The *shared* items are added to each interpreter's ``__main__`` | |
module. Not all objects are shareable. Shareable objects include | |
the builtin singletons, :class:`str` and :class:`bytes`, | |
and :class:`memoryview`. See :pep:`734` for more info. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made use of your suggestions. Thanks!
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add a brief sentence of why using a script would be desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to drop this capability for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eric, can we pass a function? We could either pickle it or capture a "path" to it (concatenate __module__
and __qualname__
and import)
I really don't like the aspect of passing code as strings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it supports passing any callable that can be pickled. Passing a script is an extra capability of InterpreterPoolExecutor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd remove the code as string capability -- otherwise this all looks good to me!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll drop it. I can look into adding that capability in separately later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This motivated me to add a bit more clarity in the docs. 😄