首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python并发不是并发的

Python并发不是并发的
EN

Stack Overflow用户
提问于 2021-07-25 07:45:06
回答 1查看 33关注 0票数 0

我的雇主使用Box。它的API非常慢。幸运的是,我们的文件很大程度上是静态的。每晚我可以迭代(递归地) Box文件夹,并将URL存储在本地文件中。在白天使用本地文件可以极大地提高读取和写入Box的脚本的性能。在0级开始递归搜索(爬行器)包括我们不关心的文件夹。所以我们有一个命名的列表,从级别1开始,我想以并行的方式递归搜索它们。

当我观察下面的代码(通过我隐藏的日志/打印语句)时,它似乎没有并行地在起始点下进行搜索。相反,在起点1下搜索整个树,然后在起点2下搜索树,依此类推。

我的问题是:为什么下面的代码不为for storage_dict, starting_point in zip(cache_dict_list, starting_dir_list)中的每一项并发执行爬行器方法

代码语言:javascript
复制
import asyncio
 
@asyncio.coroutine
def spider(storage_dict, dir_list):
    """Recursive storage of Box information in storage_dict."""
    storage_dict = {"key": "value"}

cache_dict_list = [dict() for x in starting_dir_list]
task_list = list()

async def main():
    for storage_dict, starting_point in zip(cache_dict_list, starting_dir_list):
        task_list.append(asyncio.create_task(spider(storage_dict, [starting_point])))
    await asyncio.gather(*task_list)

asyncio.run(main())

total_dict = dict()
total_dict.update([cache_dict.update(x) for x in cache_dict_list])
EN

回答 1

Stack Overflow用户

发布于 2021-07-25 13:39:10

原因基本上是异步不是多线程(稍后将对线程进行更多介绍)。Async基本上是对由事件循环执行的任务进行排队。因此,当您执行await asyncio.gather(*task_list)时,您基本上是在说“将所有这些任务放入队列中(Ish),然后等待它们完成。”如果在spider()中使用更多的async和await语句,则可以在队列中对其进行更多拆分,但最终仍将花费大约时间,因为一次只处理队列中的一项。

然后,我们有了threading。这(某种程度上)允许并发。但是,如果资源有限,情况也好不到哪里去,因为cpython使用全局解释器锁(GIL)。GIL意味着基本上单个python进程一次只能使用一个内核,避免了多个内核同时访问和修改数据时可能出现的问题。

但是,如果您想要真正的并发性,则可以使用multiprocessing模块。如何实现这一点可能取决于您希望如何获取和存储数据(以避免导致GIL的多核问题),但基本上它将允许您同时使用多核。

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

https://stackoverflow.com/questions/68514559

复制
相关文章

相似问题

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