Python:我如何同时发送多个http请求? (像叉子)

时间:2013-04-01 22:22:59

标签: python django process fork httprequest

假设我有办法将http request发送到服务器。如何将这些请求中的两个(或更多)同时发送到服务器?例如,可能通过fork进程?我该怎么做? (我也在使用django)

#This example is not tested...
import requests

def tester(request):
    server_url = 'http://localhost:9000/receive'

    payload = {
        'd_test2': '1234',
        'd_test2': 'demo',
        }
    json_payload = simplejson.dumps(payload)
    content_length = len(json_payload)

    headers = {'Content-Type': 'application/json', 'Content-Length': content_length}
    response = requests.post(server_url, data=json_payload, headers=headers, allow_redirects=True)

    if response.status_code == requests.codes.ok:
        print 'Headers: {}\nResponse: {}'.format(response.headers, response.text)

谢谢!

2 个答案:

答案 0 :(得分:7)

我认为你想在这里使用线程而不是分离新进程。虽然在某些情况下线程很糟糕,但这不是真的。另外,我认为你想使用concurrent.futures而不是直接使用线程(或进程)。

例如,假设您有10个网址,并且您目前正在连续执行这些网址,如下所示:

results = map(tester, urls)

但是现在,你想一次发送2个。只需将其更改为:

with concurrent.futures.ThreadPoolExecutor(max_workers=2) as pool:
    results = pool.map(tester, urls)

如果您想一次尝试4次而不是2次,只需更改max_workers即可。实际上,您应该尝试使用不同的值来查看哪种方法最适合您的程序。

如果你想做一些有点发烧友的事情,请参阅文档 - 主ThreadPoolExecutor Example几乎正是你要找的。

不幸的是,在2.7中,此模块没有附带标准库,因此您必须从PyPI安装the backport

如果您安装了pip,则应该简单如下:

pip install futures
在Unix上,

......或者sudo pip install futures

如果您没有pip,请先获取它(按照上面的链接)。


您有时希望使用进程而不是线程的主要原因是您有大量的CPU绑定计算,并且您希望利用多个CPU核心。在Python中,线程无法有效地耗尽所有核心。因此,如果任务管理器/活动监视器/任何显示您的程序在一个核心上使用100%CPU,而其他都是0%,则进程就是答案。使用futures,您只需将ThreadPoolExecutor更改为ProcessPoolExecutor


与此同时,有时你需要的不仅仅是“给我一个神奇的工人群来完成我的任务”。有时你想要运行一些非常长的工作而不是一堆小工作,或者自己对工作进行负载平衡,或者在工作之间传递数据,或者其他什么。为此,您希望使用multiprocessingthreading代替futures

很少,即使 太高级,也直接告诉Python创建一个新的子进程或线程。为此,你一直到os.fork(仅限Unix)或thread

答案 1 :(得分:1)

我会使用gevent,它可以在所谓的绿线程中启动所有这些:

# This will make requests compatible
from gevent import monkey; monkey.patch_all()
import requests

# Make a pool of greenlets to make your requests
from gevent.pool import Pool
p = Pool(10)

urls = [..., ..., ...]
p.map(requests.get, urls)

当然,这个例子提交了get,但是池被推广到将输入映射到任何函数,包括你的请求。这些greenlet将与使用fork几乎同时运行,但速度更快,重量更轻。