mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
bpo-35279: reduce default max_workers of ThreadPoolExecutor (GH-13618)
This commit is contained in:
parent
293e9f86b8
commit
9a7e5b1b42
4 changed files with 22 additions and 5 deletions
|
@ -159,6 +159,15 @@ And::
|
||||||
.. versionchanged:: 3.7
|
.. versionchanged:: 3.7
|
||||||
Added the *initializer* and *initargs* arguments.
|
Added the *initializer* and *initargs* arguments.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.8
|
||||||
|
Default value of *max_workers* is changed to ``min(32, os.cpu_count() + 4)``.
|
||||||
|
This default value preserves at least 5 workers for I/O bound tasks.
|
||||||
|
It utilizes at most 32 CPU cores for CPU bound tasks which release the GIL.
|
||||||
|
And it avoids using very large resources implicitly on many-core machines.
|
||||||
|
|
||||||
|
ThreadPoolExecutor now reuses idle worker threads before starting
|
||||||
|
*max_workers* worker threads too.
|
||||||
|
|
||||||
|
|
||||||
.. _threadpoolexecutor-example:
|
.. _threadpoolexecutor-example:
|
||||||
|
|
||||||
|
|
|
@ -129,9 +129,14 @@ class ThreadPoolExecutor(_base.Executor):
|
||||||
initargs: A tuple of arguments to pass to the initializer.
|
initargs: A tuple of arguments to pass to the initializer.
|
||||||
"""
|
"""
|
||||||
if max_workers is None:
|
if max_workers is None:
|
||||||
# Use this number because ThreadPoolExecutor is often
|
# ThreadPoolExecutor is often used to:
|
||||||
# used to overlap I/O instead of CPU work.
|
# * CPU bound task which releases GIL
|
||||||
max_workers = (os.cpu_count() or 1) * 5
|
# * I/O bound task (which releases GIL, of course)
|
||||||
|
#
|
||||||
|
# We use cpu_count + 4 for both types of tasks.
|
||||||
|
# But we limit it to 32 to avoid consuming surprisingly large resource
|
||||||
|
# on many core machine.
|
||||||
|
max_workers = min(32, (os.cpu_count() or 1) + 4)
|
||||||
if max_workers <= 0:
|
if max_workers <= 0:
|
||||||
raise ValueError("max_workers must be greater than 0")
|
raise ValueError("max_workers must be greater than 0")
|
||||||
|
|
||||||
|
|
|
@ -755,8 +755,8 @@ class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, BaseTestCase):
|
||||||
|
|
||||||
def test_default_workers(self):
|
def test_default_workers(self):
|
||||||
executor = self.executor_type()
|
executor = self.executor_type()
|
||||||
self.assertEqual(executor._max_workers,
|
expected = min(32, (os.cpu_count() or 1) + 4)
|
||||||
(os.cpu_count() or 1) * 5)
|
self.assertEqual(executor._max_workers, expected)
|
||||||
|
|
||||||
def test_saturation(self):
|
def test_saturation(self):
|
||||||
executor = self.executor_type(4)
|
executor = self.executor_type(4)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Change default *max_workers* of ``ThreadPoolExecutor`` from ``cpu_count() *
|
||||||
|
5`` to ``min(32, cpu_count() + 4))``. Previous value was unreasonably
|
||||||
|
large on many cores machines.
|
Loading…
Add table
Add a link
Reference in a new issue