2014-11-01 12 views
5

Używam modułu puli wieloprocesorowej Python do tworzenia puli procesów i przypisywania do niej zadań.Proces wieloprocesorowy Python numer

Stworzyłem 4 i proces przypisywania 2 miejsc pracy, ale stara się wyświetlić swój numer procesu, ale na ekranie po prostu zobaczyć numer jeden proces „6952” ... Gdyby nie to wydrukować numer 2 procesowego

from multiprocessing import Pool 
from time import sleep 

def f(x): 
    import os 
    print "process id = " , os.getpid() 
    return x*x 

if __name__ == '__main__': 
    pool = Pool(processes=4)    # start 4 worker processes 

    result = pool.map_async(f, (11,)) #Start job 1 
    result1 = pool.map_async(f, (10,)) #Start job 2 
    print "result = ", result.get(timeout=1) 
    print "result1 = ", result1.get(timeout=1) 

Wynik: -

result = process id = 6952 
process id = 6952 
[121] 
result1 = [100] 
+0

Używasz Windows? – dano

+0

@ dano-yes ....., – user1050619

Odpowiedz

2

To tylko kwestia czasu. System Windows musi odrodzić 4 procesy w Pool, które następnie należy uruchomić, zainicjować i przygotować do konsumpcji z poziomu Queue. W systemie Windows wymaga to każdego procesu podrzędnego, aby ponownie zaimportować moduł __main__, a instancje Queue używane wewnętrznie przez Pool powinny być niepoprawne w każdym potomku. Zajmuje to nietrywialną ilość czasu. Wystarczająco długo, w rzeczywistości, gdy oba twoje połączenia są wykonywane, zanim wszystkie procesy w Pool są jeszcze uruchomione. Można to zobaczyć, jeśli dodać trochę śledzenia na funkcję prowadzony przez każdego pracownika w Pool:

while maxtasks is None or (maxtasks and completed < maxtasks): 
    try: 
     print("getting {}".format(current_process())) 
     task = get() # This is getting the task from the parent process 
     print("got {}".format(current_process())) 

wyjściowa:

getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
process id = 5145 
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
process id = 5145 
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
result = [121] 
result1 = [100] 
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-3, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-4, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 

Jak widać, Worker-1 uruchamia się i konsumuje zarówno zadania przed pracownikami 2-4 nigdy nie próbuj konsumować z poziomu Queue. Jeśli dodasz sleep połączenia po instancję Pool w głównym procesie, ale przed wywołaniem map_async, zobaczysz różne procesy obsłużyć każde żądanie:

getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-3, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-4, started daemon)> 
# <sleeping here> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
process id = 5183 
got <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 
process id = 5184 
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 
result = [121] 
result1 = [100] 
got <ForkServerProcess(ForkServerPoolWorker-3, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-4, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)> 
got <ForkServerProcess(ForkServerPoolWorker-2, started daemon)> 

(Należy pamiętać, że dodatkowe "getting/"got" wypowiedzi widać są strażnicy są wysyłani do każdego procesu, aby je zamknąć w sposób gratyfikacyjny).

Używając języka Python 3.x w systemie Linux, mogę odtworzyć to zachowanie, używając kontekstów 'spawn' i 'forkserver', ale nie 'fork'. Prawdopodobnie dlatego, że rozwidlenie procesów potomnych jest znacznie szybsze niż utworzenie ich i ponowne zaimportowanie __main__.

0

Drukuje 2 identyfikatory procesu.

result = process id = 6952 <=== process id = 6952 
process id = 6952 <=== process id = 6952 
[121] 
result1 = [100] 

Jest tak, ponieważ proces roboczy zakończył się szybko i jest gotowy do przetworzenia kolejnego żądania.

result = pool.map_async(f, (11,)) #Start job 1 
result1 = pool.map_async(f, (10,)) #Start job 2 

W kodzie powyżej, twój pracownik zakończył pracę i wrócił z powrotem do puli i był gotowy, aby zakończyć pracę 2. To może zdarzyć się dla wielu powodów. Najczęstsze z nich są takie, że pracownik jest zajęty lub nie jest gotowy.

Oto przykład, w którym będziemy mieć 4 pracowników, ale tylko jeden z nich będzie gotowy od razu. W ten sposób wiemy, który z nich wykona pracę.

# https://gist.github.com/dnozay/b2462798ca89fbbf0bf4 

from multiprocessing import Pool,Queue 
from time import sleep 

def f(x): 
    import os 
    print "process id = " , os.getpid() 
    return x*x 

# Queue that will hold amount of time to sleep 
# for each worker in the initialization 
sleeptimes = Queue() 
for times in [2,3,0,2]: 
    sleeptimes.put(times) 

# each worker will do the following init. 
# before they are handed any task. 
# in our case the 3rd worker won't sleep 
# and get all the work. 
def slowstart(q): 
    import os 
    num = q.get() 
    print "slowstart: process id = {0} (sleep({1}))".format(os.getpid(),num) 
    sleep(num) 

if __name__ == '__main__': 
    pool = Pool(processes=4,initializer=slowstart,initargs=(sleeptimes,)) # start 4 worker processes 
    result = pool.map_async(f, (11,)) #Start job 1 
    result1 = pool.map_async(f, (10,)) #Start job 2 
    print "result = ", result.get(timeout=3) 
    print "result1 = ", result1.get(timeout=3) 

przykład:

$ python main.py 
slowstart: process id = 97687 (sleep(2)) 
slowstart: process id = 97688 (sleep(3)) 
slowstart: process id = 97689 (sleep(0)) 
slowstart: process id = 97690 (sleep(2)) 
process id = 97689 
process id = 97689 
result = [121] 
result1 = [100] 
+0

gist na https://gist.github.com/dnozay/b2462798ca89fbbf0bf4 – dnozay

Powiązane problemy