这会导致死锁或错误模式吗?
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。
下面这种使用线程池的方式会不会死锁?还是不喜欢这种模式?如果是这样,还有什么选择。
将 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。