这会导致死锁或错误模式吗?

Will this cause a deadlock or a bad pattern?

下面这种使用线程池的方式会不会死锁?还是不喜欢这种模式?如果是这样,还有什么选择。

pool 传递给线程中 运行 的函数,该函数又调用 运行 同一池中的函数。

from concurrent.futures import ThreadPoolExecutor
from time import sleep


def bar():
    sleep(2)
    return 2


def foo(pool):
    sleep(2)
    my_list = [pool.submit(bar) for i in range(4)]
    return [i.result() for i in my_list]


pool = ThreadPoolExecutor(10)
my_list = [pool.submit(foo, pool) for i in range(2)]
for i in my_list:
    print(i.result())

这是一种从本身由 ThreadPoolExecutor 启动的线程中生成线程的安全方法。如果 ThreadPoolExecutor 本身是 thread-safe,这可能不是必需的。输出显示了在这种情况下如何有 10 个并发线程。

from concurrent.futures import ThreadPoolExecutor
from time import sleep


BAR_THREADS = 4
FOO_THREADS = 2

def bar(_):
    print('Running bar')
    sleep(1)

def foo(_):
    print('Running foo')
    with ThreadPoolExecutor(max_workers=BAR_THREADS) as executor:
        executor.map(bar, range(BAR_THREADS))

with ThreadPoolExecutor(max_workers=FOO_THREADS) as executor:
    executor.map(foo, range(FOO_THREADS))

print('Done')

输出:

Running foo
Running foo
Running bar
Running bar
Running bar
Running bar
Running bar
Running bar
Running bar
Running bar
Done

Will the following way of using a thread pool cause a deadlock? ... If so, what is the alternative?

一种替代方法是使用对工作线程数没有硬性限制的线程池。不幸的是,concurrent.futures.ThreadPoolExecutor class 并不是那么复杂。您要么必须自己编写,要么找到第三方提供的。 (我不是 big-time Python 程序员,所以我不知道 off-hand。)

天真的替代方案 thread-pool 可能会在任何时候调用 submit() 并且所有现有工作人员都很忙时创建一个新工作人员。另一方面,这会使您很容易 运行 通过创建太多线程使程序内存不足。如果在工作人员完成其任务时有太多其他工作人员处于空闲状态,则稍微复杂一点的线程池也可能会杀死该工作人员。

更复杂的策略是可能的,但在编写代码之前,您可能必须更深入地考虑应用程序的需求和 patterns-of-use。