0

我正在使用 Python concurrent.futures,执行父多线程,每个父线程执行子线程。当 ThreadPoolExecutor 少于所需的父线程数时,我会饿死并且程序卡住。

什么是最好的方法:

1. 使用 const ThreadPoolExecutor

2.不要挨饿

请在下面找到示例代码:

import time
import sys
import concurrent.futures


MAX_THREAD_EXECUTORS = 5
threadPool = concurrent.futures.ThreadPoolExecutor(MAX_THREAD_EXECUTORS)
threads = []
command_threads = []


def main():
    start_tests()
    join_threads()


def start_tests():
    for i in range(1,14):
       threads.append(threadPool.submit(start_test_flow, i))


def start_test_flow(test):
    print(f"Start test flow for: {test}")
    execute_commands()
    join_command_threads()
    

def execute_commands():
    for i in range(1,5):
        command_threads.append(threadPool.submit(start_command, i))


def start_command(command):
    print(f"Start command for: {command}")
    time.sleep(120)


def join_threads():
    for thread in threads:
        result = thread.result()
        print(f"test result={result}")


def join_command_threads():
    for thread in command_threads:
        result = thread.result()
        print(f"command result={result}")

if __name__ == '__main__':
    main()
    sys.exit(0)

最好的问候, Moshe

4

1 回答 1

1

您实际需要的最小线程数是不确定的,并且取决于时间,尽管有一个数字(13 + 1,即每个父线程一个线程和至少一个运行子线程的线程)可以保证你永远不会停滞不前。最有可能发生的是您正在快速创建 5 个父线程,然后等待创建更多的父线程子线程,因为您只有 5 个工作线程。但是,在您能够创建 4 个子线程(在 中execute_commands)并运行它们完成之前,父线程将不会完成,因此您会被卡住。

现在,例如,插入对time.sleep(1)in 函数的调用start_tests,如下所示:

def start_tests():
    for i in range(1,14):
       threads.append(threadPool.submit(start_test_flow, i))
       time.sleep(1)

这将允许创建 4 个子线程并且会有一些进展。但根据时间的不同,您最终可能会停滞不前。为了保证您永远不会停止,您必须睡眠足够长的时间以允许所有 4 个子线程完成,然后再尝试启动下一个父线程。

底线是您没有足够的工作线程 (13 + 1) 来保证您不会停顿。

于 2020-07-02T12:20:55.757 回答