我有一个程序,当前正在使用current.current.futures.ThreadPoolExecutor并发运行多个任务。这些任务通常受I/O约束,涉及对本地数据库和远程REST API的访问。但是,这些任务本身可以分为子任务,这也将从并发中受益。
我希望的是,在任务中使用并发.futures.ThreadPoolExecutor是安全的。我已经编写了一个玩具示例,它似乎可以工作:
import concurrent.futures
def inner(i, j):
return i, j, i**j
def outer(i):
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = {executor.submit(inner, i, j): j for j in range(5)}
results = []
for future in concurrent.futures.as_completed(futures):
results.append(future.result())
return results
def main():
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = {executor.submit(outer, i): i for i in range(10)}
results = []
for future in concurrent.futures.as_completed(futures):
results.extend(future.result())
print(results)
if __name__ == "__main__":
main()
尽管这个玩具示例似乎可行,但我还是希望这是故意的。我希望是这样,因为否则,如果执行程序还使用并发.futures来利用并发性,那么使用执行程序执行任意代码将是不安全的。
最佳答案
从其他线程生成线程绝对没有问题。您的情况也是如此。
但是,迟早产生线程的开销会很高,而产生更多线程实际上会导致软件速度降低。
我强烈建议您使用 asyncio 之类的库,该库可以漂亮地异步处理任务。它是通过使用一个具有非阻塞io的线程来实现的。结果比一般线程的结果甚至更快,因为开销要小得多。
如果您不想使用asyncio,为什么不在main内部创建另一个池执行程序,并将其传递给outer()
函数呢?这样,您将拥有最多10个(2x5)的线程,而不是25(5x5)个线程,这更合理吗?
您不能传递将main()
调用到outer()
的同一outer()
执行程序,因为这可能会导致死锁(每个outer()
等待另一个outer()
完成,然后才能安排inner()
)。
关于python - 嵌套current.futures.ThreadPoolExecutor,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44989473/