Процесс Python заблокирован urllib2

Я настроил процесс, которые читают очередь для входящих URL для загрузки, но когда urllib2 открывают соединение зависания системы.

import urllib2, multiprocessing
from threading import Thread
from Queue import Queue
from multiprocessing import Queue as ProcessQueue, Process

def download(url):
    """Download a page from an url.
    url [str]: url to get.
    return [unicode]: page downloaded.
    """
    if settings.DEBUG:
        print u'Downloading %s' % url
    request = urllib2.Request(url)
    response = urllib2.urlopen(request)
    encoding = response.headers['content-type'].split('charset=')[-1]
    content = unicode(response.read(), encoding)
    return content

def downloader(url_queue, page_queue):
    def _downloader(url_queue, page_queue):
        while True:
            try:
                url = url_queue.get()
                page_queue.put_nowait({'url': url, 'page': download(url)})
            except Exception, err:
                print u'Error downloading %s' % url
                raise err
            finally:
                url_queue.task_done()

    ## Init internal workers
    internal_url_queue = Queue()
    internal_page_queue = Queue()
    for num in range(multiprocessing.cpu_count()):
        worker = Thread(target=_downloader, args=(internal_url_queue, internal_page_queue))
        worker.setDaemon(True)
        worker.start()

    # Loop waiting closing
    for url in iter(url_queue.get, 'STOP'):
        internal_url_queue.put(url)

    # Wait for closing
    internal_url_queue.join()

# Init the queues
url_queue = ProcessQueue()
page_queue = ProcessQueue()

# Init the process
download_worker = Process(target=downloader, args=(url_queue, page_queue))
download_worker.start()

От другого модуля я могу добавить URL и когда я хочу, я могу остановить процесс и ожидать закрытие процесса.

import module

module.url_queue.put('http://foobar1')
module.url_queue.put('http://foobar2')
module.url_queue.put('http://foobar3')
module.url_queue.put('STOP')
downloader.download_worker.join()

Проблема состоит в том, что, когда я использую urlopen ("ответ = urllib2.urlopen (запрос)") это остается всеми заблокированными.

Нет никакой проблемы, если я называю загрузку () функцией или когда я использую только потоки без Процесса.

8
задан Davide Muzzarelli 26 January 2010 в 02:37
поделиться

1 ответ

Проблема здесь не является Urllib2, а использование многопроцессорного модуля. При использовании многопроцессорного модуля под Windows вы не должны использовать код, который работает сразу при импорте вашего модуля - вместо этого поместите вещи в основной модуль внутри , если __name __ == '__ Main __' блок. См. Раздел «Безопасный импорт основного модуля» здесь .

Для вашего кода внесите это изменение в модуле загрузчика:

#....
def start():
    global download_worker
    download_worker = Process(target=downloader, args=(url_queue, page_queue))
    download_worker.start()

и в основном модуле:

import module
if __name__=='__main__':
    module.start()
    module.url_queue.put('http://foobar1')
    #....

, потому что вы этого не сделали, каждый раз, когда подпроцесс был запущен, он снова будет запущен основной код Начните еще один процесс, вызывая зависание.

4
ответ дан 6 December 2019 в 00:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: