2013-06-29 14 views
17

Pierwsze pytanie dotyczy różnicy między wartością a menedżerem().Współdzielona zmienna w procesie wieloprocesorowym Pythona

Po drugie, czy można udostępniać zmienną całkowitą bez użycia wartości? Poniżej znajduje się mój przykładowy kod. To, czego chcę, to uzyskanie dyktatu o wartości liczby całkowitej, a nie wartości. To, co zrobiłem, to zmienić wszystko po procesie. Czy istnieje łatwiejszy sposób?

from multiprocessing import Process, Manager 

def f(n): 
    n.value += 1 

if __name__ == '__main__': 
    d = {} 
    p = [] 

    for i in range(5): 
     d[i] = Manager().Value('i',0) 
     p.append(Process(target=f, args=(d[i],))) 
     p[i].start() 

    for q in p: 
     q.join() 

    for i in d: 
     d[i] = d[i].value 

    print d 
+0

Ważne: http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing –

Odpowiedz

19

Podczas korzystania Value masz ctypes obiektu w pamięci współdzielonej, że domyślnie jest zsynchronizowany za pomocą RLock. Podczas korzystania z Manager otrzymujesz obiekt SynManager, który steruje procesem serwera, który pozwala manipulować wartościami obiektów innymi procesami. Możesz utworzyć wiele serwerów proxy za pomocą tego samego menedżera; nie ma potrzeby tworzenia nowego menedżera w pętli:

manager = Manager() 
for i in range(5): 
    new_value = manager.Value('i', 0) 

Manager mogą być współużytkowane przez komputery, a Value jest ograniczona do jednego komputera. Value będzie szybszy (uruchom poniższy kod, aby zobaczyć), więc myślę, że powinieneś go użyć, chyba że potrzebujesz obsługi dowolnych obiektów lub dostępu do nich przez sieć.

import time 
from multiprocessing import Process, Manager, Value 

def foo(data, name=''): 
    print type(data), data.value, name 
    data.value += 1 

if __name__ == "__main__": 
    manager = Manager() 
    x = manager.Value('i', 0) 
    y = Value('i', 0) 

    for i in range(5): 
     Process(target=foo, args=(x, 'x')).start() 
     Process(target=foo, args=(y, 'y')).start() 

    print 'Before waiting: ' 
    print 'x = {0}'.format(x.value) 
    print 'y = {0}'.format(y.value) 

    time.sleep(5.0) 
    print 'After waiting: ' 
    print 'x = {0}'.format(x.value) 
    print 'y = {0}'.format(y.value) 

Podsumowując:

  1. Zastosowanie Manager tworzenie wielu obiektów udostępnionych, w tym dicts i list. Użyj opcji Manager w celu udostępniania danych między komputerami w sieci.
  2. Zastosowanie Value lub Array gdy nie jest to konieczne w celu wymiany informacji w sieci i typy w ctypes są wystarczające dla potrzeb.
  3. Value jest szybsza niż Manager.

Warning

Przy okazji wymiany danych między procesami/wątków należy unikać, jeśli to możliwe. Powyższy kod prawdopodobnie będzie działał zgodnie z oczekiwaniami, ale zwiększy czas potrzebny na wykonanie foo, a rzeczy będą dziwne. Porównaj powyższe z:

def foo(data, name=''): 
    print type(data), data.value, name 
    for j in range(1000): 
     data.value += 1 

Aby to działało, musisz mieć Lock.

Nie jestem szczególnie dobrze poinformowany o tym wszystkim, więc może ktoś inny przyjdzie i zaoferuje więcej wglądu. Pomyślałem, że udzielę odpowiedzi, ponieważ pytanie nie przyciągało uwagi. Mam nadzieję, że trochę pomaga.

+0

Czy możemy dodać dowolną wartość do Array? Nie mogę dodać żadnej wartości do Array. – user2435611

+2

@ user2435611, ['Array'] (http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Array) da ci wspólną tablicę ctypes. Musisz zdecydować, jaki rodzaj danych przechowujesz wcześniej i podać kod [typ kodu] (http://docs.python.org/2/library/array.html#module-array). Na przykład 'a = Array ('c', 10)' tworzy tablicę ciągów jednoliterowych o długości 10. Do tablicy można dodać nowe pozycje: 'a [0] = 'b''.Nie możesz dodać * żadnej * wartości do tablicy, zobacz [listę kodów typów] (http://docs.python.org/2/library/array.html#module-array). – ChrisP

+0

Więc powinniśmy zdecydować wcześniej o wielkości tablicy i nie możemy jej rozszerzyć? jeśli tak, lepiej dla mnie używać funkcji manager.list(). Dzięki za pomoc :) – user2435611

Powiązane problemy