function of `with` in `concurrent.futures`
Using a concurrent.futures.Executor
in a with
statement is equivalent to calling Executor.shutdown
after using it – causing the executor to wait for all tasks to complete. An Executor
used in a with
guarantees proper shutdown of concurrent tasks even if an error occurs inside the with
block.
Executor.shutdown(wait=True)
Signal the executor that it should free any resources that it is using when the currently pending futures are done executing. Calls to
Executor.submit()
andExecutor.map()
made after shutdown will raiseRuntimeError
.[...]
You can avoid having to call this method explicitly if you use the
with
statement, which will shutdown theExecutor
(waiting as ifExecutor.shutdown()
were called with wait set toTrue
): [...]
concurrent.futures
is not well documented. When you create an executor it must be shutdown to terminate its threads or processes. That code will signal the threads to exit by pushing a None
command to them and then wait for them to complete. In your first case, had you added executor.shutdown()
you'd see the delay. It was there anyway - the program still took 10 seconds to exit.
The executor can be used as a context manager (it as __enter__
and __exit__
methods). When it exits the "with" block, __exit__
is called and it in turn does the shutdown
call for you.