urllib2 urlopen将在多处理中阻塞

时间:2017-09-28 04:02:20

标签: python multiprocessing urllib2

我想利用多处理来加速每家公司的报告生成器

以下是测试脚本:

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

1 个答案:

答案 0 :(得分:1)

这不是一个多处理问题。通过观察所有任务大约在同一时间开始,您可以看到多处理正常工作。

任务执行时间几乎完全由本地端点在http://localhost/fee_calculate/generate-single的响应时间决定。你是如何运行这台服务器的?如果您观察每个报告的执行时间,您会注意到它们以~10秒的步长增加,这是您在服务器端(sleep(10))人为强加的处理延迟。

我怀疑您的本地服务器只是单线程的,因此一次只能处理一个请求。这意味着每个请求必须在处理下一个请求之前完成,因此当您发出这样的多个并发请求时,您实际上不会减少处理时间。