我有以下代码:
def getdata(page, hed, limit):
data = []
print page
datarALL = []
url = 'http://...WithTotal=true&cultureid=1&offset={0}&limit={1}'.format(value_offset, value_limit)
print page
print url
responsedata = requests.get(url, data=data, headers=hed, verify=False)
if responsedata.status_code == 200: # 200 for successful call
responsedata = responsedata.text
jsondata = json.loads(responsedata)
if "results" in jsondata:
if jsondata["results"]:
datarALL = datarALL + jsondata["results"]
print "page {} finished".format(page)
return data
def start(data, auth_token):
# # --- Get data from API --
hed = {'Authorization': 'Bearer ' + auth_token, 'Accept': 'application/json'}
urlApi = 'http://...WithTotal=true&cultureid=1&offset=0&limit=1'
responsedata = requests.get(urlApi, data=data, headers=hed, verify=False)
num_of_records = int(math.ceil(responsedata.json()['total']))
value_limit = 249 # Number of records per page.
num_of_pages = num_of_records / value_limit
print num_of_records
print num_of_pages
pages = [i for i in range(0, num_of_pages - 1)]
from concurrent.futures import ThreadPoolExecutor, as_completed
datarALL = []
with ThreadPoolExecutor(max_workers=num_of_pages) as executor:
futh = [executor.submit(getdata(page, hed, value_limit), page) for page in pages]
for data in as_completed(futh):
datarALL = datarALL + data.result()
return datarALL
基本上start()
创建页面,getdata()
每页运行。
印刷品显示给我:
0
http://...WithTotal=true&cultureid=1&&offset=0&limit=249
page 0 finished
1
http:/...WithTotal=true&cultureid=1&&offset=249&limit=249
page 1 finished
etc...
但是,我希望所有页面将在同一时间创建,然后每个线程在线程获得CPU时间时运行,但实际上发生的是仅在getdata()
完成时创建下一页。这意味着线程在这里是无用的。我应该注意,每个getdata()
通话大约需要4-5分钟才能完成。
我怀疑问题出在这里
futh = [executor.submit(getdata(page, hed, value_limit), page) for page in pages]
它等待getdata()
完成之后才能运行下一个循环。
如何修复它并使它与线程一起使用?
答案 0 :(得分:3)
问题是您根本不在执行程序中执行任务。相反,您要调用5分钟函数,然后尝试将其 result 作为任务执行:
[executor.submit(getdata(page, hed, value_limit), page) for page in pages]
getdata(page, hed, value_limit)
是一个函数调用:它调用getdata
并等待其返回值。
您需要做的就是将函数本身传递给submit
,如下所示:
executor.submit(getdata, page, hed, value_limit)
我不确定您要如何使用多余的, page
,但是如果您想要(future, page)
元组的列表,那就是:
[(executor.submit(getdata, page, hed, value_limit), page) for page in pages]
答案 1 :(得分:1)
您必须向executor.submit
提交一个函数(实际上没有调用它!)。因此,在您的特定情况下,应在hed
函数中修复value_limit
和getdata
参数,以使其具有单个参数page
的功能。
最简单的解决方案可能如下所示:
getdata_partial = lambda page: getdata(page, hed, value_limit)
然后您可以按如下所示使用它:
futh = [executor.submit(getdata_partial, page) for page in pages]
另一种可能的解决方案是使用functools.partial。您可能会发现它更加优雅,但想法仍然相同。