2017-02-04 2 views
1

Ich habe versucht, ein einfaches Multiprocessing-Programm zu erstellen, das den Wert von X in einer bestimmten Zeit erfasst und den Wert nicht in der Lesezeit überspringt. Dies ist der Code:Python liest mehrere Werte im Multiprocessing

from multiprocessing import Process, Pipe 
from time import sleep 

def f(conn): 
    x=0 
    for i in xrange(0,20): 
     x+=1 
     sleep(0.1) 
     conn.send(x) 
    conn.close() 

if __name__ == '__main__': 
    parent_conn, child_conn = Pipe() 
    p = Process(target=f, args=(child_conn,)) 
    p.start() 
    for i in xrange(0,5): 
     print parent_conn.recv() 
     sleep(0.4) 
    p.join() 

Grob gesagt, was ich von Code erwarten oben, ist dies:

>>> 
4 
8 
16 
20 

sondern gab der IDLE mir diese Ausgabe:

>>> 
1 
2 
3 
4 
5 

Und so weiter, bis es 20 erreicht. Gibt es einen Befehl, den Puffer zu löschen? oder ähnliches?

danke im voraus.

Antwort

1

Das Problem ist, dass recv() den nächsten Wert in der Pipe und nicht die letzte erhält.

So, nach 4 Iterationen, f tat send 4 Artikel in pipe, so dass das Rohr sieht wie folgt aus:

1, 2, 3, 4 

und dem Hauptprozess wird recv1:

2, 3, 4 

nach dem anderen 4 Iterationen von send:

2, 3, 4, 5, 6, 7, 8 

und der Hauptprozess recv es 2. Um nur die letzten zu erhalten müssen Sie das Rohr leeren zuerst:

from multiprocessing import Process, Pipe 
from time import sleep 

def f(conn): 
    x=0 
    for i in xrange(0,20): 
     x+=1 
     sleep(0.1) 
     conn.send(x) 
    conn.close() 

if __name__ == '__main__': 
    parent_conn, child_conn = Pipe() 
    p = Process(target=f, args=(child_conn,)) 
    p.start() 
    for i in xrange(0,5): 
     sleep(0.4) 
     # `recv` all values, keep only the last one 
     last = None 
     while parent_conn.poll(): 
      last = parent_conn.recv() 
     print(last) 
    p.join() 
+0

so, soll ich verwenden poll(), um das Rohr zu löschen. aber wie ist das möglich? Wenn die Umfrage() falsch wird? Ich meine, es sollte Ende 20 sein, oder? oder ich vermisse etwas hier? es funktioniert natürlich, aber ich habe nur verblüfft, wie das Ding funktioniert. danke – aji

+0

@aji 'poll' prüft, ob es noch Elemente in der Pipe gibt, die empfangen werden können, so dass Sie es als' has_elements' verstehen können. Wenn "poll" falsch wird, hören Sie die while-Schleife auf. Das Entleeren des Rohres erfolgt mit der Wiederholung 'recv'. – hansaplast