在并行处理中使用对象并"restart"这些对象



目标

我想从网页中检索信息(并行(。一旦其中一个";爬行器";找到我们正在寻找的结果,我们终止,如果没有,我们刷新刚刚查看的页面并再次搜索。换句话说:

  • 在3个进程中打开网页(同一页面,延迟X秒(
  • 一有结果就立即返回(每个过程不是一次全部返回(
  • 如果此结果为==True,则完成并终止池
  • 如果没有,我们调用.restart()并再次将其添加到池中
  • 重复

代码侧

scrape类

让我们首先定义Scraper对象:

import random
import time
import multiprocessing
# Result simulation array, False is much more likely than True
RES = [True, False, False, False, False, False, False, False, False, False, False, False, False]
class Scrape:
def __init__(self, url):
self.url = url
self.result = None
def get_result(self):
return self.result
def scrape(self):
# Go to url
# simulate work
time.sleep(random.randrange(5))
# simulate result
result = RES[random.randrange(13)]
# Return what we found on the page
self.result = result
def restart(self):
# >> Some page refreshing
self.scrape()

所以我们去网页做一些工作(scrape(,然后我们可以通过get_result访问结果,如果这不是我们想要的,我们可以称之为restart。请注意,实际上这个类要复杂得多,因此重新创建它将浪费启动驱动程序的时间(与通过restart重用同一个类相比(

并行代码

这就是我遇到的问题,虽然我使用了map数百次,但我不知道如何保留Scrape对象,调用restart并将它们再次添加到池中。我一直在想这样的事情,但这并没有像我希望的那样起作用。也许排队是一种更好的方法,但我不熟悉。

# Function to create the scrapers
def obj_create(url):
print('Create')
a = Scrape(url)
a.scrape()
return a
# Function to restart the scraper
def obj_restart(a):
print('Restart')
a.restart()
a.scrape()
return a
# Callback
def call_back(scrape_obj):
if scrape_obj.get_result():
pool.terminate()
# Also somehow return the result...
else:
# Restart and add again
pool.apply_async(obj_restart, scrape_obj, callback=call_back)

pool = multiprocessing.Pool(3)
url = 'test.com'
delay = 0.001
n = 3
for i in range(n):
time.sleep(delay)
pool.apply_async(obj_create, url, callback=call_back)
pool.close()
pool.join()

我尽力制作了这个可复制的例子,并尽我所能对其进行了解释,但如果有什么不清楚的地方,请告诉我!

python

在并行中

你似乎从未听说过GIL?如果是这样的话,我很抱歉让你失望了,但因为它,你无法获得真正的并行性

不止这些。在你描述的情况下。。你根本不需要。因为大多数时候你的线程都会被网络接口阻止回复。因此,您需要的是一个好的异步框架a-ka事件循环,它将优化您的执行,从而将阻塞减少到可能的最小程度。

让我来介绍一下aiohttp。它为您提供了正确实现的HTTP(s(调用,而光荣的异步为您提供取消、重试和处理错误的整洁机制。

尤其要看一看集合。

p.S.multiprocessing将使事情变得平行,但由于任务的IO限制性质,这在这里是一种过度的做法。您可以留在同一个进程中,通过拒绝这种并行性来避免所有的多处理地狱,这种并行性在大多数情况下都会被阻塞。

最新更新