просто реализована многопроцессорность и очереди демо, интересно, если есть какие-либо улучшения?


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

вот моя реализация, а не уверен, если это правильный способ делать вещи:

#coding=utf8

import multiprocessing
from multiprocessing import JoinableQueue
import urllib2
import logging
import os

logging.basicConfig(level=logging.DEBUG)

URLS = [
        'http://stackoverflow.com/q/2243542/94962',
        'http://docs.python.org/library/logging.html',
        'http://www.python.org/dev/peps/pep-3101/',
        'http://news.ycombinator.com/',
        'http://www.evernote.com/about/learn_more/',
        'http://news.php.net/php.internals/55293',
        ]

POOL_SIZE = multiprocessing.cpu_count()

DEST_DIR = '/tmp/pytest/'

url_q = JoinableQueue()

class Worker(multiprocessing.Process):

    def run(self):
        while True:
            try:
                url = url_q.get()
                logging.info('%(process_name)s processing %(url)s' % {
                    'process_name': multiprocessing.current_process().name,
                    'url':url,
                    })
                web_cnt = urllib2.urlopen(url).read()
                url_filename = url[7:].replace('/', '-').strip('.html') + '.html'
                with open(os.path.join(DEST_DIR, url_filename), 'w') as f:
                    f.write(web_cnt)
                url_q.task_done()
            except Exception:
                logging.exception('error')


workers = []
for i in range(POOL_SIZE):
    worker = Worker()
    worker.name = 'worker%s'%i
    workers.append(worker)
    worker.start()

for url in URLS:
    url_q.put(url)

url_q.join()

print 'workers have done stuff'

for worker in workers:
    worker.terminate()


664
5
задан 9 сентября 2011 в 09:09 Источник Поделиться
Комментарии
2 ответа

Когда вы ловите исключение, я предлагаю лесозаготовки полное исключение так что вы можете сказать, что пошло не так.

Я предлагаю не используя аббревиатуры, как web_cnt. Код легче читать, когда вы заклинания вещи.

На самом деле не существует причин, чтобы использовать многопроцессорность здесь, поскольку ваши задачи ИО не привязаны к ЦП. Я бы, наверное, использовать библиотеку eventlet для этого.

Мультипроцессирование класс, бассейн, около половины код дублирующего поведение.

2
ответ дан 9 сентября 2011 в 01:09 Источник Поделиться

Вы должны пройти url_q очереди в конструкторе вместо того, чтобы использовать его в качестве глобальной переменной.

2
ответ дан 9 сентября 2011 в 10:09 Источник Поделиться