2014-09-26 4 views
6

Ich möchte alle Threads von einem einzelnen Worker beenden.Wie tötet man alle Pool-Mitarbeiter im Multiprozess?

Ich habe einen Thread-Pool mit 10 Beschäftigten:

def myfunction(i): 
    print(i) 
    if (i == 20): 
     sys.exit() 

p = multiprocessing.Pool(10, init_worker) 

for i in range(100): 
    p.apply_async(myfunction, (i,)) 

Mein Programm nicht stoppen und die anderen Prozesse weiterarbeiten, bis alle 100 Iterationen abgeschlossen sind. Ich möchte den Pool vollständig aus dem Thread stoppen, der sys.exit() aufruft. Die Art, wie es derzeit geschrieben wird, stoppt nur den Worker, der sys.exit() aufruft.

Antwort

11

Dies funktioniert nicht so, wie Sie es beabsichtigen, da das Aufrufen von sys.exit() in einem Arbeitsprozess nur den Worker beendet. Es wirkt sich nicht auf den übergeordneten Prozess oder die anderen Worker aus, da es sich um separate Prozesse handelt und die Erhöhung SystemExit nur den aktuellen Prozess betrifft. Sie müssen dem übergeordneten Prozess ein Signal senden, um ihm mitzuteilen, dass er heruntergefahren werden sollte. Eine Möglichkeit, dies zu tun für Ihren Anwendungsfall wäre ein Event in einem multiprocessing.Manager Server erstellt verwenden:

import multiprocessing 

def myfunction(i, event): 
    if not event.is_set(): 
     print i 
    if i == 20: 
     event.set() 

if __name__ == "__main__": 
    p= multiprocessing.Pool(10) 
    m = multiprocessing.Manager() 
    event = m.Event() 
    for i in range(100): 
     p.apply_async(myfunction , (i, event)) 
    p.close() 

    event.wait() # We'll block here until a worker calls `event.set()` 
    p.terminate() # Terminate all processes in the Pool 

Ausgang:

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 

Wie in Lukes Antwort darauf hingewiesen, gibt es ein Rennen hier : Es gibt keine Garantie, dass alle Arbeiter in der Reihenfolge laufen, also ist es möglich, dass myfunction(20, ..) zum Beispiel vor myfuntion(19, ..) ausgeführt wird. Es ist auch möglich, dass andere Worker nach 20 ausgeführt werden, bevor der Hauptprozess auf das festgelegte Ereignis reagieren kann. Ich habe die Größe des Rennfensters reduziert, indem ich den if not event.is_set(): Aufruf vor dem Drucken i hinzufüge, aber es existiert noch.

+1

vielen Dank +1 – N3TC4t

+0

Was ist der variable Pool im obigen Code? –

+0

@RajanChaudan Ein Tippfehler! Ich habe es jetzt behoben. – dano

1

Sie können dies nicht tun.

Auch wenn Sie alle Ihre Prozesse unter i == 20 beenden konnten, konnten Sie nicht sicher sein, dass nur 20 Zahlen gedruckt wurden, da Ihre Prozesse in einer nicht-deterministischen Reihenfolge ausgeführt werden.

Wenn Sie nur 20 Prozesse ausführen möchten, müssen Sie dies von Ihrem Master-Prozess (dh Ihrer Regelschleife) aus verwalten.