Ограничение количества процессов в многопроцессорном python

Мое требование - генерировать hundreds of HTTP POST requests per second. Я делаю это с помощью urllib2.

def send():
    req = urllib2.Request(url)
    req.add_data(data)
    response = urllib2.urlopen(req)

while datetime.datetime.now() <= ftime:
    p=Process(target=send, args=[])
    p.start()
    time.sleep(0.001)

Проблема заключается в том, что этот код sometimes for some iterations содержит одно из следующих исключений:

HTTP 503 Service Unavailable.
URLError: <urlopen error [Errno -2] Name or service not known>

Я попытался использовать requests(HTTP for humans), но у меня есть некоторые проблемы с этим модулем. Кажется, что requests отправляет http-пакеты на прокси-сервер, даже если целевой компьютер находится в одной локальной сети. Я не хочу, чтобы пакеты отправлялись на прокси-сервер.

Ответ 1

Самый простой способ ограничить количество параллельных подключений - использовать пул потоков:

#!/usr/bin/env python
from itertools import izip, repeat
from multiprocessing.dummy import Pool # use threads for I/O bound tasks
from urllib2 import urlopen

def fetch(url_data):
    try:
        return url_data[0], urlopen(*url_data).read(), None
    except EnvironmentError as e:
        return url_data[0], None, str(e)

if __name__=="__main__":
    pool = Pool(20) # use 20 concurrent connections
    params = izip(urls, repeat(data)) # use the same data for all urls
    for url, content, error in pool.imap_unorderred(fetch, params):
        if error is None:
           print("done: %s: %d" % (url, len(content)))
        else:
           print("error: %s: %s" % (url, error))

503 Service Unavailable - ошибка сервера. Он может не справиться с нагрузкой.

Name or service not known является ошибкой dns. Если вам нужно сделать много запросов; установить/включить локальный сервер DNS-кеширования.