Skip to content

Instantly share code, notes, and snippets.

@aeros
Last active January 22, 2020 05:42
Show Gist options
  • Save aeros/2e73c8d6dccc94fd863967715826c78d to your computer and use it in GitHub Desktop.
Save aeros/2e73c8d6dccc94fd863967715826c78d to your computer and use it in GitHub Desktop.
"""Requires
https://github.com/aeros/cpython/tree/bpo39349-add-cancel_futures-to-Executor.shutdown.
See https://github.com/python/cpython/pull/18057 for details.
"""
import concurrent.futures as cf
import time
def wait_return(duration, result):
time.sleep(duration)
return result
def show_executor_shutdown(executor_type, wait, cancel_futures):
executor = executor_type(max_workers=2)
futures = [executor.submit(wait_return, .1, 42) for _ in range(8)]
executor.shutdown(wait=wait, cancel_futures=cancel_futures)
for fut in futures:
print(f"{fut._result=}, {fut._state=}")
if __name__ == "__main__":
print("ThreadPoolExecutor:")
print("wait=True and cancel_futures=False:")
show_executor_shutdown(executor_type=cf.ThreadPoolExecutor,
wait=True,
cancel_futures=False)
print()
print("wait=True and cancel_futures=True:")
show_executor_shutdown(executor_type=cf.ThreadPoolExecutor,
wait=True,
cancel_futures=True)
print()
print("wait=False and cancel_futures=False:")
show_executor_shutdown(executor_type=cf.ThreadPoolExecutor,
wait=False,
cancel_futures=False)
print()
print("wait=False and cancel_futures=True:")
show_executor_shutdown(executor_type=cf.ThreadPoolExecutor,
wait=False,
cancel_futures=True)
print()
print("ProcessPoolExecutor:")
print("wait=True and cancel_futures=False:")
show_executor_shutdown(executor_type=cf.ProcessPoolExecutor,
wait=True,
cancel_futures=False)
print()
print("wait=True and cancel_futures=True:")
show_executor_shutdown(executor_type=cf.ProcessPoolExecutor,
wait=True,
cancel_futures=True)
print()
# Note: wait=False was omitted for PPE due to deadlocks.
# See https://gist.github.com/aeros/d1ff62b730426584413bca0c8f2ed99d
# for an example.
@aeros
Copy link
Author

aeros commented Jan 22, 2020

Specs:
Python 3.9+ (PR branch for python/cpython#18057)
Linux kernel 5.4.8
Intel i5-4460

Results:

[aeros:~/repos/aeros-cpython]$ ./python show_executor_shutdown.py
ThreadPoolExecutor:
wait=True and cancel_futures=False:
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'

wait=True and cancel_futures=True:
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'

wait=False and cancel_futures=False:
fut._result=None, fut._state='RUNNING'
fut._result=None, fut._state='RUNNING'
fut._result=None, fut._state='PENDING'
fut._result=None, fut._state='PENDING'
fut._result=None, fut._state='PENDING'
fut._result=None, fut._state='PENDING'
fut._result=None, fut._state='PENDING'
fut._result=None, fut._state='PENDING'

wait=False and cancel_futures=True:
fut._result=None, fut._state='RUNNING'
fut._result=None, fut._state='RUNNING'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'
fut._result=None, fut._state='CANCELLED'

ProcessPoolExecutor:
wait=True and cancel_futures=False:
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'

wait=True and cancel_futures=True:
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=42, fut._state='FINISHED'
fut._result=None, fut._state='CANCELLED_AND_NOTIFIED'
fut._result=None, fut._state='CANCELLED_AND_NOTIFIED'
fut._result=None, fut._state='CANCELLED_AND_NOTIFIED'
fut._result=None, fut._state='CANCELLED_AND_NOTIFIED'
fut._result=None, fut._state='CANCELLED_AND_NOTIFIED'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment