Skip to content

Instantly share code, notes, and snippets.

@novicecpp
Last active June 11, 2024 15:40
Show Gist options
  • Save novicecpp/0a78f131f33fbaa56c4fece844b36a90 to your computer and use it in GitHub Desktop.
Save novicecpp/0a78f131f33fbaa56c4fece844b36a90 to your computer and use it in GitHub Desktop.
from concurrent.futures import ProcessPoolExecutor
from concurrent.futures.process import BrokenProcessPool
import time
import requests
import sys
import ctypes
import traceback
import signal
import psutil
import os
def handler(signum, frame):
print("Forever is over!")
raise TimeoutError("end of time")
def fn(n):
print(f'return {n}*5')
return n*5
def fn_timeout(n):
print('sleeping 11 secs')
time.sleep(11)
print('fn_timeout finished running')
return n*5
def fn_timeout_signal(n):
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)
print('sleeping 11 secs')
time.sleep(11)
print('fn_timeout finished running')
signal.alarm(0)
return n*5
def fn_exception(n):
time.sleep(1)
raise TypeError('just raise')
return n*5
def fn_coredump(n):
time.sleep(1)
#https://codegolf.stackexchange.com/a/22383
ctypes.string_at(1)
return n*5
print('running..')
with ProcessPoolExecutor(max_workers=1) as executor:
future = executor.submit(fn, 4)
outputs = future.result(timeout=5)
print(f'output from future: {outputs}')
print('running timeout')
try:
with ProcessPoolExecutor(max_workers=1) as executor:
future = executor.submit(fn_timeout, 5)
try:
outputs = future.result(timeout=5)
except TimeoutError as e:
print(type(e), ''.join(traceback.format_tb(e.__traceback__)))
print('this is timeout')
# thanks to https://stackoverflow.com/questions/42782953/python-concurrent-futures-how-to-make-it-cancelable
def kill_child_processes(parent_pid, sig=signal.SIGTERM):
try:
parent = psutil.Process(parent_pid)
except psutil.NoSuchProcess:
return
children = parent.children(recursive=True)
for process in children:
process.send_signal(sig)
print('close and kill')
executor.shutdown(wait=False)
kill_child_processes(os.getpid())
except Exception as e:
print(type(e), ''.join(traceback.format_tb(e.__traceback__)))
print('should not be here')
print('running timeout signal')
try:
with ProcessPoolExecutor(max_workers=1) as executor:
future = executor.submit(fn_timeout_signal, 5)
outputs = future.result() # fully trust installed signal to raise exception
except TimeoutError as e:
print(type(e), ''.join(traceback.format_tb(e.__traceback__)))
print('this is timeout with sigalarm')
print('running exception')
try:
with ProcessPoolExecutor(max_workers=1) as executor:
future = executor.submit(fn_exception, 6)
outputs = future.result(timeout=5)
except Exception as e:
print(type(e), ''.join(traceback.format_tb(e.__traceback__)))
print('this is exception')
print('running crash')
try:
with ProcessPoolExecutor(max_workers=1) as executor:
future = executor.submit(fn_coredump, 7)
outputs = future.result(timeout=5)
except BrokenProcessPool as e:
print(type(e), ''.join(traceback.format_tb(e.__traceback__)))
print('this is crash')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment