Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ThreadPoolExecutor with context manager

I don't understand why this code is behaving in different way. In the first case, the code will print 'elo' and after 19 seconds we will see '3'.

In other case we will be first wait 19 seconds, and after that we will see 'elo'.

Could you explain me that?

from concurrent.futures import ThreadPoolExecutor

def wait_on_future():
    f = 3
    import time
    time.sleep(19)
    print(f)

executor = ThreadPoolExecutor(max_workers=2)
executor.submit(wait_on_future)
print("elo")

vs

from concurrent.futures import ThreadPoolExecutor

def wait_on_future():
    f = 3
    import time
    time.sleep(19)
    print(f)

with ThreadPoolExecutor(max_workers=2) as executor:      
    executor.submit(wait_on_future)
print("elo")
like image 473
Mariusz Avatar asked Feb 09 '18 11:02

Mariusz


People also ask

Why is it a good idea to use a ThreadPoolExecutor as a context manager when you can?

Why Use a ThreadPoolExecutor? ThreadPoolExecutors provide a simple abstraction around spinning up multiple threads and using these threads to perform tasks in a concurrent fashion. Adding threading to your application can help to drastically improve the speed of your application when used in the right context.

Is ThreadPoolExecutor faster?

The ThreadPoolExecutor is designed to speed-up your program by executing tasks concurrently. Nevertheless, in some use cases, using the ThreadPoolExecutor can make your program slower. Sometimes dramatically slower than performing the same task in a for loop.

How many employees does ThreadPoolExecutor have?

There is no maximum number of worker threads in the ThreadPoolExecutor.

What is ThreadPoolExecutor?

ThreadPoolExecutor is an ExecutorService to execute each submitted task using one of possibly several pooled threads, normally configured using Executors factory methods. It also provides various utility methods to check current threads statistics and control them.


1 Answers

Your first program does not explicitly close the pool. You submit your task with executor.submit(), which is a non-blocking call. Your main program processes to print statement immediately and just hangs there until all threads have finished after 19 seconds.

Your second program uses with statement, which in this context is blocking. with ThreadPoolExecutor() has an implicit shutdown(wait=True), and it blocks there until all threads have completed processing. See https://docs.python.org/3/library/concurrent.futures.html

This makes your program1 identical in functionality as is your program 2:

executor = ThreadPoolExecutor(max_workers=2)
executor.submit(wait_on_future)
executor.shutdown(wait=True)
print("elo")

Hope this helps.

like image 58
Hannu Avatar answered Sep 22 '22 12:09

Hannu