2014-11-01 7 views
5

Utilizzo il modulo del pool di multiprocessing Python per creare un pool di processi e assegnarvi lavori.Processo di multiprocessing Python numero

ho creato 4 processo e l'assegnazione di 2 posti di lavoro, ma cercando di mostrare il loro numero di processo, ma sul display ho solo vedere il numero unico processo "6952" ... Non dovrebbe stampare il numero 2 processo

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) 

Risultato: -

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

Si sta utilizzando Windows? – dano

+0

@ dano-sì ....., – user1050619

risposta

2

Si tratta solo di tempi. Windows ha bisogno di generare 4 processi nel Pool, che devono quindi essere avviati, inizializzati e preparati a consumare dallo Queue. Su Windows, questo richiede che ogni processo figlio reimportazione il modulo __main__ e che le istanze utilizzate internamente dallo Pool siano deselezionate in ciascun figlio. Questo richiede una quantità di tempo non trascurabile. Abbastanza a lungo, infatti, quando tutte e due le vostre chiamate-vengono eseguite prima che tutti i processi nello Pool siano ancora attivi e in esecuzione. Si può vedere questo se si aggiunge un po 'di tracciare la funzione gestita da ciascun lavoratore nel 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())) 

uscita:

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)> 

Come si può vedere, Worker-1 avvia e consuma entrambe le attività prima che i lavoratori 2-4 mai provare a consumare dal Queue. Se si aggiunge una chiamata sleep dopo si crea un'istanza della Pool nel processo principale, ma prima di chiamare map_async, vedrete diversi processi gestire ogni richiesta:

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)> 

(Si noti che l'extra "getting/"got" affermazioni che vedete siano sentinelle inviate ad ogni processo per chiuderle con grazia).

Utilizzando Python 3.x su Linux, sono in grado di riprodurre questo comportamento utilizzando i contesti 'spawn' e 'forkserver', ma non 'fork'. Presumibilmente perché la forking dei processi figlio è molto più veloce che generarli e fare una reimportazione di __main__.

0

Stampa 2 ID processo.

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

Questo perché il processo di lavoro è terminato rapidamente ed era pronto per elaborare un'altra richiesta.

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

Nel codice precedente, il vostro lavoratore ha compiuto il lavoro ed è tornato indietro alla piscina ed era pronto a completare lavoro 2. Ciò può avvenire per diverse ragioni. I più frequenti sono che il lavoratore sia occupato o non sia pronto.

Ecco un esempio in cui avremo 4 lavoratori, ma solo uno sarà pronto subito. Quindi sappiamo quale avrà intenzione di fare il lavoro.

# 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) 

esempio:

$ 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 su https://gist.github.com/dnozay/b2462798ca89fbbf0bf4 – dnozay