-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
bpo-39207: Spawn workers on demand in ProcessPoolExecutor #19453
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 4 commits
674574a
5e5e4f1
04e5927
28bb669
04e6b29
75690c7
d390e51
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 |
|---|---|---|
|
|
@@ -486,10 +486,16 @@ def _prime_executor(self): | |
| pass | ||
|
|
||
| def test_processes_terminate(self): | ||
| self.executor.submit(mul, 21, 2) | ||
| self.executor.submit(mul, 6, 7) | ||
| self.executor.submit(mul, 3, 14) | ||
| self.assertEqual(len(self.executor._processes), 5) | ||
| def acquire_lock(lock): | ||
| lock.acquire() | ||
|
|
||
| mp_context = get_context() | ||
| sem = mp_context.Semaphore(0) | ||
| for _ in range(3): | ||
| self.executor.submit(acquire_lock, sem) | ||
|
aeros marked this conversation as resolved.
|
||
| self.assertEqual(len(self.executor._processes), 3) | ||
| for _ in range(3): | ||
| sem.release() | ||
| processes = self.executor._processes | ||
| self.executor.shutdown() | ||
|
|
||
|
|
@@ -964,6 +970,37 @@ def test_ressources_gced_in_workers(self): | |
| mgr.shutdown() | ||
| mgr.join() | ||
|
|
||
| def test_saturation(self): | ||
| executor = self.executor_type(4) | ||
| def acquire_lock(lock): | ||
| lock.aquire() | ||
|
|
||
| mp_context = get_context() | ||
| sem = mp_context.Semaphore(0) | ||
| job_count = 15 * executor._max_workers | ||
| for _ in range(job_count): | ||
| executor.submit(acquire_lock, sem) | ||
| self.assertEqual(len(executor._processes), executor._max_workers) | ||
| for _ in range(job_count): | ||
| sem.release() | ||
| executor.shutdown() | ||
|
aeros marked this conversation as resolved.
Outdated
|
||
|
|
||
| def test_idle_process_reuse_one(self): | ||
| executor = self.executor_type() | ||
| executor.submit(mul, 21, 2).result() | ||
| executor.submit(mul, 6, 7).result() | ||
| executor.submit(mul, 3, 14).result() | ||
| self.assertEqual(len(executor._processes), 1) | ||
| executor.shutdown() | ||
|
|
||
| def test_idle_process_reuse_multiple(self): | ||
| executor = self.executor_type() | ||
| executor.submit(mul, 12, 7).result() | ||
| executor.submit(mul, 33, 25) | ||
| executor.submit(mul, 25, 26).result() | ||
| executor.submit(mul, 18, 29) | ||
| self.assertEqual(len(executor._processes), 2) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test might be subject to race conditions, as indicated in https://buildbot.python.org/all/#/builders/296/builds/46: Instead, I think it would probably make more sense to check I'll take a look at this again tomorrow, after the buildbot tests have completed. |
||
| executor.shutdown() | ||
|
|
||
| create_executor_tests(ProcessPoolExecutorTest, | ||
| executor_mixins=(ProcessPoolForkMixin, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Workers in :class:`~concurrent.futures.ProcessPoolExecutor` are now spawned on | ||
| demand, only when there are no available idle workers to reuse. This optimizes | ||
| startup overhead and reduces the amount of lost CPU time to idle workers. | ||
| Patch by Kyle Stanley. |
Uh oh!
There was an error while loading. Please reload this page.