我想利用多处理来加速每家公司的报告生成器
以下是测试脚本:
from multiprocessing import Pool
import os, time, random, json, urllib, urllib2, uuid
def generate_report(url, cookie, company_id, period, remark):
try:
start = time.time()
print('Run task %s (%s)... at: %s \n' % (company_id, os.getpid(), start))
values = {
'companies': json.dumps([company_id]),
'month_year': period,
'remark': remark
}
data = urllib.urlencode(values)
headers = {
'Cookie': cookie
}
url = "%s?pid=%s&uuid=%s" % (url, os.getpid(), uuid.uuid4().get_hex())
request = urllib2.Request(url, data, headers)
response = urllib2.urlopen(request)
content = response.read()
end = time.time()
print 'Task %s runs %0.2f seconds, end at: %s \n' % (company_id, (end - start), end)
return content
except Exception as exc:
return exc.message
if __name__=='__main__':
print 'Parent process %s.\n' % os.getpid()
p = Pool()
url = 'http://localhost/fee_calculate/generate-single'
cookie = 'xxx'
company_ids = [17,15,21,19]
period = '2017-08'
remark = 'test add remark from python script'
results = [p.apply_async(generate_report, args=(url,cookie,company_id,period,remark)) for company_id in company_ids]
for r in results:
print(r.get())
但我得到的结果如下:
Run task 17 (15952)... at: 1506568581.98
Run task 15 (17192)... at: 1506568581.99
Run task 21 (18116)... at: 1506568582.01
Run task 19 (1708)... at: 1506568582.05
Task 17 runs 13.50 seconds, end at: 1506568595.48
{"success":true,"info":"Successed!"}
Task 15 runs 23.60 seconds, end at: 1506568605.59
{"success":true,"info":"Successed!"}
Task 21 runs 34.35 seconds, end at: 1506568616.36
{"success":true,"info":"Successed!"}
Task 19 runs 44.38 seconds, end at: 1506568626.44
{"success":true,"info":"Successed!"}
似乎urllib2.urlopen(请求)已被阻止,请求未被并行发送,但是有序。
为了测试多处理,脚本fee_calculate / generate-single只有以下重要代码:
sleep(10)
请给我建议,谢谢。
PS: 平台:windows10,python2.7,4 CPU
答案 0 :(得分:1)
这不是一个多处理问题。通过观察所有任务大约在同一时间开始,您可以看到多处理正常工作。
任务执行时间几乎完全由本地端点在http://localhost/fee_calculate/generate-single
的响应时间决定。你是如何运行这台服务器的?如果您观察每个报告的执行时间,您会注意到它们以~10秒的步长增加,这是您在服务器端(sleep(10)
)人为强加的处理延迟。
我怀疑您的本地服务器只是单线程的,因此一次只能处理一个请求。这意味着每个请求必须在处理下一个请求之前完成,因此当您发出这样的多个并发请求时,您实际上不会减少处理时间。