2014-11-16 3 views
0

Этот вопрос возникает в результате попытки объединить протоколирование с многопроцессорным пулом. Под Linux нечего делать; модуль, содержащий мой рабочий метод пула, наследует основные свойства журнала приложения. В Windows я должен инициализировать регистратор в каждом процессе, что я делаю, запустив pool.map_async с помощью метода initializer. Проблема в том, что метод работает так быстро, что он запускается несколько раз в некоторых процессах, а не в других. Я могу заставить его работать правильно, если добавить короткий метод времени, но это кажется неэлегантным.Распределение сил пула многопроцессорности пула процесса

Есть ли способ заставить пул распределить процессы равномерно?

(некоторые фон: http://plumberjack.blogspot.de/2010/09/using-logging-with-multiprocessing.html)

код выглядит следующим образом, я не могу опубликовать весь модуль ;-) Вызов заключается в следующем:

  # Set up logger on Windows platforms 
      if os.name == 'nt': 
       _ = pool.map_async(ml.worker_configurer, 
            [self._q for _ in range(mp.cpu_count())]) 

Функция ml.worker_configurer это:

def worker_configurer(queue, delay=True): 
    h = QueueHandler(queue) 
    root = logging.getLogger() 
    root.addHandler(h) 
    root.setLevel(logging.DEBUG) 
    if delay: 
     import time 
     time.sleep(1.0) 
    return 

Новый рабочий configurer

def worker_configurer2(queue): root = logging.getLogger() if not root.handlers: h = QueueHandler(queue) root.addHandler(h) root.setLevel(logging.DEBUG) return

+0

Как выглядит ваш код? –

+0

Добавлен к моему вопросу. –

+0

«Пул» действительно полезен для быстрой распараллеливания, но не очень хорош, если вы хотите мелкозернистый контроль над своими процессами. –

ответ

0

Вы можете сделать что-то вроде этого:

sub_logger = None 

def get_logger(): 
    global sub_logger 
    if sub_logger is None: 
     # configure logger 

    return sub_logger 

def worker1(): 
    logger = get_logger() 
    # DO WORK 

def worker2(): 
    logger = get_logger() 
    # DO WORK 

pool = multiprocessing.Pool(processes=multiprocessing.cpu_count()) 
result = pool.map_async(worker1, some_data) 
result.get() 
result = pool.map_async(worker2, some_data) 
result.get() 
# and so on and so forth 

Поскольку каждый процесс имеет свое собственное пространство памяти (и, таким образом, собственный набор глобальных переменных), вы можете установить начальный глобальный логгер None и только настройте регистратор, если он еще не был настроен ранее.

+0

Хм, я вижу, как это работает, но я уже реализовал конфигуратор, который проверяет существующий регистратор для обработчиков, так как это дублирование обработчика, которое вызывает проблему. Вы видите какие-то недостатки в моем решении? Лучше ли глобальный подход? –

Смежные вопросы