首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌套concurrent.futures.ThreadPoolExecutor

嵌套concurrent.futures.ThreadPoolExecutor
EN

Stack Overflow用户
提问于 2017-07-08 18:26:26
回答 1查看 6.8K关注 0票数 24

我有一个程序,我目前正在使用concurrent.futures.ThreadPoolExecutor并发运行多个任务。这些任务通常是I/O绑定的,包括对本地数据库和远程REST的访问。但是,这些任务本身也可以分为子任务,这也将受益于并发性。

我希望在任务中使用concurrent.futures.ThreadPoolExecutor是安全的。我编写了一个玩具例子,这个例子似乎很有效:

代码语言:javascript
复制
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()

虽然这个玩具例子似乎有效,但我希望有一些信心,这是故意的。我希望是这样,因为否则使用executor执行任意代码是不安全的,如果它也使用concurrent.futures来利用并发性。

EN

回答 1

Stack Overflow用户

发布于 2018-06-30 16:33:18

从其他线程产生线程是绝对没有问题的。你的案子没什么不同。

但是迟早,产生线程的开销会相当高,并且产生更多的线程实际上会导致您的软件慢下来。

我强烈建议使用像https://docs.python.org/3/library/asyncio.html这样的库,它能够很好地异步处理任务。它通过使用一个具有非阻塞io的线程来做到这一点。结果可能是比普通线程更快的,因为开销要小得多。

如果不希望使用异步,为什么不在main中创建另一个池执行器,并将其传递给outer()函数?这样,而不是25 (5x5)线程,您将有最多10 (2x5),这是更合理的吗?

您不能传递同一个main()执行器,该执行器调用outer()outer(),因为它可能导致死锁(由每个outer()在调度inner()之前等待另一个outer()完成)。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44989473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档