import concurrent.futures import tempfile import os import shutil import subprocess def task(kind): dirname = tempfile.mkdtemp() f_w = open(os.path.join(dirname, "stdout.txt"), "w") if kind == "subprocess_devnull": with subprocess.Popen("dir", shell=True, stdout=subprocess.DEVNULL): pass elif kind == "subprocess_noredirect": with subprocess.Popen("dir > NUL", shell=True): pass elif kind == "subprocess_redirfile": with subprocess.Popen("dir", shell=True, stdout=f_w): pass elif kind == "nosubprocess": print("Starting", file=f_w) import time time.sleep(0.1) print("Stop", file=f_w) else: raise ValueError("invalid value {}".format(kind)) f_w.close() shutil.rmtree(dirname) def execute_tasks(N, parallel, kind): results = [] def task_done(f): if f.exception() is None: results.append(True) else: #print(f.exception()) results.append(f.exception()) threadpool = concurrent.futures.ThreadPoolExecutor(max_workers=parallel) for i in range(N): threadpool.submit(task, kind).add_done_callback(task_done) threadpool.shutdown() errors = [r for r in results if r is not True] print(FMTSTRING.format(kind, parallel, "OK" if len(errors) == 0 else "{} errors".format(len(errors)))) import platform print("Platform:", platform.platform()) print() FMTSTRING = "{:25} {:<10} {:10}" print(FMTSTRING.format(*"task_type #threads result".split())) execute_tasks(10, 2, "subprocess_redirfile") execute_tasks(10, 1, "subprocess_redirfile") execute_tasks(10, 2, "subprocess_devnull") execute_tasks(10, 1, "subprocess_devnull") execute_tasks(10, 2, "subprocess_noredirect") execute_tasks(10, 1, "subprocess_noredirect") execute_tasks(10, 2, "nosubprocess") execute_tasks(10, 1, "nosubprocess")