Pytanie Korzystanie z przetwarzania wieloprocesowego. Przetwarzaj z maksymalną liczbą równoczesnych procesów


Mam Python kod:

from multiprocessing import Process

def f(name):
    print 'hello', name

if __name__ == '__main__':
    for i in range(0, MAX_PROCESSES):
        p = Process(target=f, args=(i,))
        p.start()

który działa dobrze. Jednak, MAX_PROCESSES jest zmienna i może być dowolną wartością między 1 i 512. Ponieważ używam tego kodu tylko na komputerze z 8 Rdzenie, muszę się dowiedzieć, czy możliwe jest ograniczenie liczby procesów dozwolonych do uruchomienia w tym samym czasie. Sprawdziłem multiprocessing.Queue, ale nie wygląda na to, czego potrzebuję - lub może interpretuję dokumenty nieprawidłowo.

Czy istnieje sposób na ograniczenie liczby jednoczesnych multiprocessing.Processdziała?


39
2018-01-02 15:51


pochodzenie


dla i w zakresie (0, min (MAX_PROCESSES, 8)): - Jacob
@Jacob Nadal chcę, aby wszystkie MAX_PROCESSES działały. Powyższy kod jest skrócony dla uproszczenia, ale główna funkcja jest wywoływana do 512 razy (stąd pętla). Zastanawiam się, czy istnieje sposób na kolejkowanie procesów. - Brett
więc chcesz skonfigurować master / worker i chcesz ograniczyć liczbę pracowników? - Jacob
@Jacob Tak, to może być lepszy sposób na sformułowanie tego. - Brett


Odpowiedzi:


To może być najrozsądniejsze w użyciu multiprocessing.Pool co tworzy pulę procesów roboczych w oparciu o maksymalną liczbę rdzeni dostępnych w systemie, a następnie zasadniczo przekazuje zadania w miarę, jak stają się dostępne rdzenie.

Przykład ze standardowych dokumentów (http://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers) pokazuje, że można również ręcznie ustawić liczbę rdzeni:

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=4)              # start 4 worker processes
    result = pool.apply_async(f, [10])    # evaluate "f(10)" asynchronously
    print result.get(timeout=1)           # prints "100" unless your computer is *very* slow
    print pool.map(f, range(10))          # prints "[0, 1, 4,..., 81]"

Przydaje się również informacja, że ​​istnieje multiprocessing.cpu_count() metoda liczenia liczby rdzeni w danym systemie, jeśli to konieczne w kodzie.

Edycja: Oto szkic kodu, który wydaje się działać w konkretnym przypadku:

import multiprocessing

def f(name):
    print 'hello', name

if __name__ == '__main__':
    pool = multiprocessing.Pool() #use all available cores, otherwise specify the number you want as an argument
    for i in xrange(0, 512):
        pool.apply_async(f, args=(i,))
    pool.close()
    pool.join()

58
2018-01-02 16:02



To wygląda obiecująco. Spróbuję zaadaptować logikę do mojego kodu, a ja ją opublikuję / przyjmiemy tutaj, gdy ją uruchomię. - Brett
W porządku, przygotowałem wersję, która wydaje się działać dobrze dla twojego konkretnego przypadku i dodana do postu powyżej. - treddy
multiprocessing.cpu_count()-1 or 1 może być użyteczną heurystyką do decydowania o tym, jak wiele procesów może działać równolegle: -1 pozwala uniknąć blokowania systemu przez monopolizację wszystkich rdzeni, ale jeśli jest tylko jeden procesor, to or daje wdzięczny powrót do pojedynczego biegu. - andybuckley
Co się stanie, jeśli moja funkcja będzie wymagała ciężkiej pracy i niewielkiego przetwarzania? Czy używa 10 wątków na 4 rdzeniowym komputerze, wpływając w jakiś sposób na program? - Abhidemon