2015-05-22 6 views
2

Вот пример игрушки, который у меня есть. У меня есть класс Singleton, который используется в большом скрипте python. Я хочу, чтобы запустить этот сценарий много раз с несколькими входами: Одноэлементного шаблон не нужен здесь, но в моем более сложном реальном использовании есть причина, чтобы использовать егоСостояние, используемое при многопроцессорной обработке при использовании одноэлементных классов

import time 
import multiprocessing 


class TestClass(object): 
    instance = None 

    @classmethod 
    def get_instance(cls): 
    if cls.instance is None: 
     print 'creating instance' 
     cls.instance = TestClass() 
    return cls.instance 

    def __init__(self): 
    self.data = [] 


def worker(num): 
    tc = TestClass.get_instance() 
    time.sleep(0.1) 
    tc.data.append(num) 
    return tc.data 


def main(): 
    pool = multiprocessing.Pool(processes=1) 
    res = pool.map(worker, range(10)) 

    print res 
    print TestClass.get_instance().data 


main() 

Когда я запускаю приведенный выше код, его кажется, состояние TestClass.instance (полу-?) общий. Результат:

[[0, 1, 2], [0, 1, 2], [0, 1, 2], ..., [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] 

Если изменить число процессов до 10 я получаю:

[[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]] 

Это результат я хотел.

(Если я печатаю TestClass.get_instance().data после вызова pool.map() Затем я получаю пустой список.)

Что такое объяснение такого поведения? Есть ли способ остановить это разделение состояния и получить второй вывод, но сохранить контроль над количеством процессов в пуле?

Редактировать: Когда я выбираю N экземпляров для запуска функции с M различными аргументами. Экземпляр создается N раз. В идеале я хочу создать M экземпляров, по одному для каждого аргумента.

+0

Почему вы используете одноэлементный шаблон здесь с многопроцессорной обработкой? Кажется, это немного лишнее, поскольку каждый подпроцесс получает свое собственное состояние интерпретатора (* хотя и разветвлено от родителя *). –

+0

Его просто пример с игрушкой, реальный сценарий имеет гораздо больше возможностей, и некоторые из них означают, что я хочу использовать синглтон по разным причинам. – camz

+0

Но вы понимаете, что ваш пример использования одноэлементного вида бесполезен? Так как вы каждый раз запускаете несколько экземпляров '' TestClass'' в каждом процессе? Если у вас '' процессы = 10'', вы создадите 10 экземпляров '' TestClass''. –

ответ

1

Okay; перефразирование:

Я хочу создать N процессов для запуска функции для M различных аргументов ; но вместо N рабочих процессов я хочу M worker процессов; один за перестановку аргументов.

Это действительно невозможно с multiprocessing.Pool, поскольку оно не предназначено для этого прецедента. Это больше похоже на встроенную функцию map(), где вы применяете функцию к последовательности входов, которые связаны с процессором по нескольким рабочим процессам.

должен самостоятельно управлять набором рабочих процессов, используя multiprocessing.Process().

+0

Спасибо за объяснение. С процессами = 1 я думал, что он создаст все 10 процессов, но только запустит 1 сразу. Но, похоже, он создает 1 и использует его 10 раз. – camz

+0

Действительно :) Спасибо, что помогли мне понять вашу проблему! –

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