summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2016-08-07 17:19:20 (GMT)
committerGregory P. Smith <greg@krypto.org>2016-08-07 17:19:20 (GMT)
commit50abe877ee6f50ebd9cfe228d314220e071fa3c6 (patch)
tree9858ef0cc4b0b534eb18fc539d3ac62c256f3584 /Lib
parentd0d24fd1ae05a2aea84165cf0aae98f75a5203c8 (diff)
downloadcpython-50abe877ee6f50ebd9cfe228d314220e071fa3c6.zip
cpython-50abe877ee6f50ebd9cfe228d314220e071fa3c6.tar.gz
cpython-50abe877ee6f50ebd9cfe228d314220e071fa3c6.tar.bz2
Issue #27664: Add to concurrent.futures.thread.ThreadPoolExecutor()
the ability to specify a thread name prefix.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/concurrent/futures/thread.py11
-rw-r--r--Lib/test/test_concurrent_futures.py24
2 files changed, 32 insertions, 3 deletions
diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py
index 3ae442d..6266f38 100644
--- a/Lib/concurrent/futures/thread.py
+++ b/Lib/concurrent/futures/thread.py
@@ -81,12 +81,13 @@ def _worker(executor_reference, work_queue):
_base.LOGGER.critical('Exception in worker', exc_info=True)
class ThreadPoolExecutor(_base.Executor):
- def __init__(self, max_workers=None):
+ def __init__(self, max_workers=None, thread_name_prefix=''):
"""Initializes a new ThreadPoolExecutor instance.
Args:
max_workers: The maximum number of threads that can be used to
execute the given calls.
+ thread_name_prefix: An optional name prefix to give our threads.
"""
if max_workers is None:
# Use this number because ThreadPoolExecutor is often
@@ -100,6 +101,7 @@ class ThreadPoolExecutor(_base.Executor):
self._threads = set()
self._shutdown = False
self._shutdown_lock = threading.Lock()
+ self._thread_name_prefix = thread_name_prefix
def submit(self, fn, *args, **kwargs):
with self._shutdown_lock:
@@ -121,8 +123,11 @@ class ThreadPoolExecutor(_base.Executor):
q.put(None)
# TODO(bquinlan): Should avoid creating new threads if there are more
# idle threads than items in the work queue.
- if len(self._threads) < self._max_workers:
- t = threading.Thread(target=_worker,
+ num_threads = len(self._threads)
+ if num_threads < self._max_workers:
+ thread_name = '%s_%d' % (self._thread_name_prefix or self,
+ num_threads)
+ t = threading.Thread(name=thread_name, target=_worker,
args=(weakref.ref(self, weakref_cb),
self._work_queue))
t.daemon = True
diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py
index cdb9308..46b069c 100644
--- a/Lib/test/test_concurrent_futures.py
+++ b/Lib/test/test_concurrent_futures.py
@@ -154,6 +154,30 @@ class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, unittest.Tes
for t in threads:
t.join()
+ def test_thread_names_assigned(self):
+ executor = futures.ThreadPoolExecutor(
+ max_workers=5, thread_name_prefix='SpecialPool')
+ executor.map(abs, range(-5, 5))
+ threads = executor._threads
+ del executor
+
+ for t in threads:
+ self.assertRegex(t.name, r'^SpecialPool_[0-4]$')
+ t.join()
+
+ def test_thread_names_default(self):
+ executor = futures.ThreadPoolExecutor(max_workers=5)
+ executor.map(abs, range(-5, 5))
+ threads = executor._threads
+ del executor
+
+ for t in threads:
+ # We don't particularly care what the default name is, just that
+ # it has a default name implying that it is a ThreadPoolExecutor
+ # followed by what looks like a thread number.
+ self.assertRegex(t.name, r'^.*ThreadPoolExecutor.*_[0-4]$')
+ t.join()
+
class ProcessPoolShutdownTest(ProcessPoolMixin, ExecutorShutdownTest, unittest.TestCase):
def _prime_executor(self):