我正在做一个网络爬虫,我有一些“睡眠”功能,使爬网相当长。 现在我在做:
for speciality in range(1,25):
for year in range(1997, 2017):
for quarter in [1,2]:
deal_with (driver, year, quarter, speciality, ok)
deal_with
函数正在打开几个网页,等待几秒钟完成html下载,然后继续。执行时间非常长:有25*10*2=500个循环,每个循环不少于一分钟。你知道吗
我想用我的4个物理内核(8个线程)来享受并行性。 我读到了龙卷风,多重处理,作业库。。。我真的不能决定一个简单的解决方案来适应我的代码。你知道吗
任何见解欢迎:-)
归根结底,只有两种基本方法可以扩展这样的任务:
多重处理
启动许多Python进程,并将任务分发给每个进程。这是你认为对你有帮助的方法。你知道吗
尽管您可以使用任何适当的包装器,但仍可以使用一些示例代码来说明其工作原理:
如果这是你想要的,你现在可以停止阅读了。你知道吗
异步执行
在这里,您只满足于一个线程或进程,但您不希望它空闲地等待网络读取或磁盘查找之类的内容返回—您希望它在等待的同时继续做其他更重要的事情。你知道吗
真正的本机异步I/O支持在Python3中提供,在Twisted networking库之外的Python2.7中不存在。你知道吗
那有什么区别?你知道吗
我在这里的主要观点是强调,从一系列技术中进行选择并不像找出真正的瓶颈在哪里那么难。你知道吗
在上面的例子中,没有任何区别。两者都遵循一个简单的模式:
因此,如果你一字不差地遵循这些示例,即使它们使用完全不同的技术,并且声称使用完全不同的技术,你也不会获得概念上的差异。你知道吗
如果按照这种模式编写,您选择的任何技术都将是徒劳的—即使您会得到一些加速,但如果您期望获得巨大的性能提升,您将非常失望。你知道吗
为什么这种模式不好?因为这不能解决你的问题。你知道吗
你的问题很简单:你必须等待。当您的进程正在等待某些东西返回时,它不能做其他任何事情!它不能为你调用更多的页面。它无法处理传入的任务。它所能做的就是等待。你知道吗
让更多的进程最终等待并不是真正的解决方案。一支必须向滑铁卢进军的军队,如果你把它分成几个团,速度不会更快——每个团最终都要睡觉,尽管他们可能在不同的时间、不同的长度睡觉,而结果是,他们几乎都会在同一时间到达。你知道吗
你需要的是一支永不停息的军队。你知道吗
那你该怎么办?你知道吗
将所有I/O任务抽象为非阻塞。这是你真正的瓶颈。如果你在等待一个网络响应,不要让糟糕的过程就这样坐以待毙——给它做点什么。你知道吗
您的任务变得有些困难,因为默认情况下,从套接字读取是阻塞的。操作系统就是这样。谢天谢地,您不需要用python3来解决这个问题(尽管这始终是首选的解决方案)asyncore库(though Twisted is comparably superior in every way)已经存在于python2.7中,可以在后台进行真正的网络读写。你知道吗
只有一种情况需要在Python中使用真正的多处理,那就是如果您正在进行CPU受限或CPU密集型的工作。从你的描述来看,好像不是这样的。你知道吗
简而言之,您应该编辑
deal_with
函数以避免初期的等待。如果需要的话,可以使用Twisted或asyncore中合适的抽象在后台等待。但不要让它完全消耗你的过程。你知道吗如果您使用的是python3,我会查看asycio module。我相信你可以用
@asyncio.coroutine
来装饰deal_with
。您可能需要调整deal_with
所做的工作,才能正确地处理事件循环。你知道吗相关问题 更多 >
编程相关推荐