2017-09-04 1 views
1

Ich versuche, mich mit dem multiprocessing Modul vertraut zu machen. Ich habe derzeit einige Probleme mit Pipe(). Ich habe ein kleines Beispiel zur Veranschaulichung meines Problems entwickelt.Multiprocessing Pipe() funktioniert nicht

Ich schrieb zwei Funktionen:

  • Eine, die Dateien in einem bestimmten Ordner (spawner)
  • Und einen anderen, der diese Dateien und kopiert sie in einem anderen Ordner (cleaner)

erkennt schafft Beide funktionieren gut. Ich habe es auch geschafft, eine Process für beide zu erstellen, so dass das Erstellen und Kopieren der Dateien gleichzeitig erfolgt.

Für den nächsten Schritt möchte ich die spawner mit der cleaner kommunizieren, dass es fertig ist, Dateien zu erstellen, so dass die letzteren beenden können. Hier

ist der Code:

import os 
from time import sleep 
import multiprocessing as mp 
from shutil import copy2 


def spawner(f_folder, pipeEnd): 
    template = 'my_file{}.txt' 
    for i in range(10): 
     new_file = os.path.join(f_folder, template.format(str(i))) 
     with open(new_file, 'w'): 
      pass 
     sleep(1) 
    pipeEnd.send(True) 
    return 


def cleaner(f_folder, t_folder, pipeEnd): 
    state = set() 
    while not pipeEnd.recv(): 
     new_files = set(os.listdir(f_folder)).difference(state) 
     state = set(os.listdir(f_folder)) 
     for file in new_files: 
      copy2(os.path.join(f_folder, file), t_folder) 
     sleep(3) 
    return 

if __name__ == '__main__': 
    receiver, sender = mp.Pipe() 
    from_folder = r'C:\Users\evkouni\Desktop\TEMP\PythonTests\subProcess\from' 
    to_folder = r'C:\Users\evkouni\Desktop\TEMP\PythonTests\subProcess\to' 
    p = mp.Process(target=spawner, args=(from_folder, sender)) 
    q = mp.Process(target=cleaner, args=(from_folder, to_folder, receiver)) 
    p.start() 
    q.start() 

Ich kann einfach nicht in der Lage sein scheinen, um es zu arbeiten .. Jede Hilfe würde geschätzt.

Antwort

2

Eine Pipe ist die falsche Lösung für Ihr Problem. Sie könnten eine Pipe verwenden, wenn Sie die Dateinamen vom Spawner an den Cleaner übergeben möchten, aber Sie versuchen, eine Markierung zu setzen. Zu diesem Zweck würde ich die Verwendung eines Event empfehlen: https://docs.python.org/2/library/multiprocessing.html#multiprocessing.Event

Dies kann als thread-sicheren (und multiprocess-safe) boolean angesehen werden. Sie würden es wie

finished = mp.Event() 
... 
finished.set() # pipeEnd.send(True) 
... 
while not finished.is_set(): # while not receiver.recv(): 
+0

Vielen Dank für die Antwort verwenden. Es hat mehr oder weniger funktioniert. Würde es Ihnen etwas ausmachen, die 'Pipe()' -Lösung zu posten, vorausgesetzt, dass ich die Dateinamen übergeben wollte? –

+0

In diesem Fall hätten Sie 'pipeEnd.send (new_file)' im Spawner (vielleicht senden Sie 'None' oder' False', wenn Sie fertig sind). Im Reiniger hättest du 'filename = pipeEnd.recv()', dann eine einfache Textverarbeitung, um den neuen Namen (im Verzeichnis dest) und 'copy2 (Dateiname, Ziel_Dateiname)' – lxop

+0

zu erhalten. Ich habe es mit 'queue' gemacht (' '' '' '' '' '_' '' _ '' '_' '' _ '' 'mit' '' ''''' ''''' mit '' '' '' '' '' '' '' '' queue'' besetzt.) Vielen Dank! –

Verwandte Themen