2017-06-30 4 views
2

Ich verwende concurrent.futures.ProcessPoolExecutor, um mehrere Instanzen von Code gleichzeitig auszuführen. Während des Laufens möchte ich die Instanzen überwachen. Ich benutze die future.running() und future.done() Funktionen dafür. Ich schrieb ein minimales Beispiel:Der Status von concurrent.futures spiegelt nicht seinen wahren Status wider.

def dummy_solver(i): 
    sleep(random()*5) 
    return i 

def foo(): 
    with concurrent.futures.ProcessPoolExecutor(max_workers=2) as pool: 
     number_of_jobs = 6 
     futures = [None] * number_of_jobs 
     for job_number in range(len(futures)): 
      futures[job_number] = pool.submit(dummy_solver, job_number) 
     while True: 
      msg = "" 
      for future in futures: 
       if future.running() is True: 
        part_msg = "Job Running  " 
       if future.done() is True: 
        part_msg = "Job Done, Result:" + str(future.result()) 
       msg = msg + " | " + part_msg 
      print("\r" + msg, end="") 
      sleep(1) 

Das beginnt 6 Arbeitsplätze und legt sie in die PoolExecutor, die auf zwei Aufträge gleichzeitig arbeiten können. Sobald ich foo beginnen, ist es das, was ich auf der Konsole:

| Job Running  | Job Running  | Job Running  | Job Running  | Job Running  | Job Running  

Dies zeigt an, dass alle Prozesse auf einmal ausgeführt werden. Ich denke, nur zwei von ihnen sollten sofort laufen. Was mache ich falsch?

Antwort

2

Hier ist ein Anfang: add

  part_msg = "" 

(oder was auch immer msg Ihnen am besten gefällt) als erste Anweisung in der

 for future in futures: 

Schleife. Wie es ist, part_msg ist nicht zurückgesetzt auf jede Schleife Iteration, also, wenn weder future.running() noch future.done() ist wahr part_msg behält nur den Wert, den es auf die vorherige Iteration hatte.

Es gibt auch eine Feinheit hier: .running() berichtet wirklich, ob die Zukunft in der internen Maschinerie so weit gekommen ist, dass ihre Ausführung nicht mehr abgebrochen werden kann. Es gibt also keine Garantie, dass höchstens max_workers Futures berichten, dass sie "rennen". Das hängt von den internen Implementierungsdetails ab, die in den Versionen variieren können. Wenn ein Arbeitsprozess eine Aufgabe startet, reiht die Maschinerie im Hauptprogramm typischerweise auch eine andere Aufgabe ein, die darauf wartet, dass eine Arbeitskraft verfügbar wird, und zu diesem Zeitpunkt melden beide Aufgaben running(), obwohl nur eine von ihnen tatsächlich ausgeführt wird.

Verwandte Themen