I can't understand difference. Help me to watch this difference. And what about ProcessPoolExecutor, is his behavior the same?
def func(task):
do_something(task)
tasks = [task for i in range(12)]
executor = ThreadPoolExecutor(4)
executor.map(func, tasks)
executor.shutdown(wait=True) # ok, here the main thread waits for others
tasks = [task for i in range(12)]
executor = ThreadPoolExecutor(4)
executor.map(func, tasks)
executor.shutdown(wait=False) # here it doesn't wait and what can happens bad?
tasks = [task for i in range(12)]
executor = ThreadPoolExecutor(4)
executor.map(func, tasks) # if i don't call shutdown ?
ThreadPoolExecutor is an Executor subclass that uses a pool of threads to execute calls asynchronously. An Executor subclass that uses a pool of at most max_workers threads to execute calls asynchronously.
Use the ThreadPoolExecutor class when you need to execute tasks that may or may not take arguments and may or may not return a result once the tasks are complete. Use the ThreadPoolExecutor class when you need to execute different types of ad hoc tasks, such as calling different target task functions.
You can wait for a task to finish in a ThreadPoolExecutor by calling the wait() module function.
From Python 3.2 onwards a new class called ThreadPoolExecutor was introduced in Python in concurrent. futures module to efficiently manage and create threads.
From the docs:
If wait is True then this method will not return until all the pending futures are done executing and the resources associated with the executor have been freed. If wait is False then this method will return immediately and the resources associated with the executor will be freed when all pending futures are done executing. Regardless of the value of wait, the entire Python program will not exit until all pending futures are done executing.
This covers the first two examples.
For the third one, since ThreadPoolExecutor
adheres to the "context manager" protocol you can use it along the with
statement in order to have the shutdown
method automatically called for as soon as execution exits the with
block.
The default is True
if you omit the parameter - or if you use it as a context manager, so using it inside the with
block is useless no matter the value of wait
.
[edit]
i edited code. See pls, there are my final questions
You only call the shutdown
method if you want to explicitly release all resources and ensure no new calls to submit
or map
will succeed. If you don't call shutdown (or use ThreadPoolExecutor
as a context manager), resources may be released only when the entire Python program exits (and it will not exit until all pending futures are done).
Calling shutdown
with wait==True
or using ThreadPoolExecutor
as a context manager will block until all pending futures are done executing.
The only use case I can think of for calling shutdown
explicitly is:
executor = ThreadPoolExecutor(4)
try:
executor.map(func, tasks)
finally:
executor.shutdown(wait=False)
To give some context, this is the code snippet from the first version of this question:
def func(task):
do_something(task)
tasks = [task for i in range(12)]
with ThreadPoolExecutor(4) as executor:
executor.map(func, tasks)
executor.shutdown(wait=True) # what is happening here?
tasks = [task for i in range(12)]
with ThreadPoolExecutor(4) as executor:
executor.map(func, tasks)
executor.shutdown(wait=False) # what is happening here?
tasks = [task for i in range(12)]
with ThreadPoolExecutor(4) as executor:
executor.map(func, tasks) # and without shutdown()?
Note that tasks = [task for i in range(12)]
is redundant - you can use just executor.map(func, range(12))
as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With