def enforce_limits(mem_in_mb=None, cpu_time_in_s=None, wall_time_in_s=None, num_processes=None, grace_period_in_s=None):
logger = multiprocessing.get_logger()
if mem_in_mb is not None:
logger.debug("restricting your function to {} mb memory.".format(mem_in_mb))
if cpu_time_in_s is not None:
logger.debug("restricting your function to {} seconds cpu time.".format(cpu_time_in_s))
if wall_time_in_s is not None:
logger.debug("restricting your function to {} seconds wall time.".format(wall_time_in_s))
if num_processes is not None:
logger.debug("restricting your function to {} threads/processes.".format(num_processes))
if grace_period_in_s is None:
grace_period_in_s = 0
def actual_decorator(func):
def wrapped_function(*args, **kwargs):
global return_value
logger = multiprocessing.get_logger()
# create a pipe to retrieve the return value
parent_conn, child_conn = multiprocessing.Pipe()
# create and start the process
subproc = multiprocessing.Process(target=subprocess_func, name=" multiproc function call", args=(func,
child_conn,
mem_in_mb,
cpu_time_in_s,
wall_time_in_s,
num_processes) + args,
kwargs=kwargs)
logger.debug("Your function is called now.")
return_value = None
# start the process
subproc.start()
child_conn.close()
try:
# read the return value
return_value = parent_conn.recv()
except EOFError: # Don't see that in the unit tests :(
logger.debug("Your function call closed the pipe prematurely -> None will be returned")
return_value = None
except:
raise
finally:
# don't leave zombies behind
subproc.join()
return (return_value);
return wrapped_function
return actual_decorator
评论列表
文章目录