2017-10-13 2 views
0

Ich habe zwei Algorithmen A und B. Beide Algorithmen nehmen die gleiche Zeichenfolge als Eingabe, führen Sie die gleiche Transformation auf string und gibt eine neue Zeichenfolge zurück.Python 3: Wie starte ich 2 Prozesse geben Sie die Antwort von dem zuerst beendet, und stoppen Sie den anderen Prozess früh

Die durchgeführte Transformation kann manchmal sehr CPU-intensiv sein, und die Algorithmen haben unterschiedliche Ansätze für das Problem. Die Algorithmen verhalten sich abhängig von der Eingabe-Zeichenkette drastisch unterschiedlich, aber ich interessiere mich nur für die Antwort, nicht für welchen Algorithmus die Transformation angewendet wird.

Ich habe einige Pseudo-Code geschrieben, um das Problem ein wenig besser zu erklären:

def process_alg1(algorithm1, input_string) 

    ans_string = algorithm1(input_string) 

    q.put(ans_string) 

def process_alg2(algorithm2, input_string) 

    ans_string = algorithm2(input_string) 

    q.put(ans_string) 


def apply_transformation(input_string): 

    q = multiprocess.Queue() 

    process_alg1(input_string) 

    process_alg2(input_string) 

    final_answer = q.get() 

    stop(slowest_process) 

Ich vermute, i-Daemon Prozesse verwenden müssen? Ich bin mir nur nicht sicher, welchen Ansatz ich überhaupt nehmen muss. Richte ich eine Pipeline zwischen Prozessen und einer Art Handler ein, die den langsameren Prozess zum Stoppen bringt? Kann ich das einfach mit Dämonen und einer Schlange machen?

Ich habe viele Beispiele für mehrere Eingaben für den gleichen Algorithmus gefunden, aber keine Beispiele für mehrere Algorithmen, die mit der gleichen Eingabe arbeiten.

Danke.

+0

Sie den Hauptprozess regelmäßig brauchen würde, um das Kind Prozess abfragen 'exitcode' Attribut, um zu bestimmen, ob es noch beendet hat. Dann müssten Sie eine Art von gemeinsam genutzter Variable ändern, die das andere Kind (oder beide) regelmäßig überprüfen, damit sie es beenden können. Siggill zu senden ist nicht nett, und hat kein direktes Windows equivent. – Aaron

+0

@Aaron, wenn ich einen Daemon-Prozess für beide verwenden und ich diese Funktion apply_transformation von einem anderen Teil meines Programms aufrufen, werden die Prozesse nach dem Aufruf apply_transformation oder nach dem Ende des gesamten Programms beendet? –

+0

Es gibt nicht so etwas wie einen Dameon-Prozess. Nur Threads – Aaron

Antwort

0

Hoffe das hilft. Verwenden Rohr statt Warteschlange:

def process_alg1(algorithm1, input_string) 

    ans_string = algorithm1(input_string) 

    q.put(ans_string) 

def process_alg2(algorithm2, input_string) 

    ans_string = algorithm2(input_string) 

    q.put(ans_string) 


def apply_transformation(input_string): 

    q = multiprocess.Queue() 

    p1 = process_alg1(input_string) 

    p2 = process_alg2(input_string) 

    p1.start() 
    p2.start() 

    while p1.is_alive() and p2.is_alive(): 
     print 'Both are still computing' 


    final_answer = q.get() 

    stop(p1 if p1.is_alive() else p2) 
+0

Ah das ist wirklich einfach und ich liebe es. Was genau meinst du mit Pipe anstelle von Queue? Im Pseudocode sieht es so aus, als ob Sie immer noch eine Warteschlange benutzen. Soll ich das tauschen? –

+0

Diese Antwort ist unvollständig und stoppt den untergeordneten Prozess nicht als die beschriebene Frage. Es gibt keine 'stop()' Funktion für Prozesse. Am nächsten wäre es, das Pid aufzusuchen und pcall zu benutzen, um es zu sigkillieren. Es gibt kein echtes Equivalent für Windows. – Aaron

+0

gibt es im Multiprocessing-Modul von Python zu beenden Methode, die Prozess beenden kann. Auch es gibt singal.SIGTERM zurück –

1

Hier ist ein minimales Beispiel:

import multiprocessing as mp 
from time import sleep 
from numpy.random import randint 

def task(n, stopsignal): 
    for x in range(n): #complex computation task steps (iterations, etc.. however you break it up) 
     with stopsignal.getlock(): 
      if stopsignal.value: 
       print(mp.current_process().name + " recieved stop signal. Terminating.") 
     time.sleep(1) #complex computation 
    print(mp.current_process().name + " returned first. attempting to halt others...") 

stopsignal = mp.Value('b', 0, lock=True) #'b' for signed 8 bit int (could use other types) 
processes = [] 
for i in range(5): #start 5 processes 
    p = Process(
      target=task, 
      name="Process_{}".format(i), 
      args=(randint(5,20),stopsignal,), 
     ) 
    p.start() 
    processes.append(p) 

while True: 
    with stopsignal.getlock(): 
     if stopsignal.value: 
      break 
    for p in processes: #check each process 
     if p.exitcode is not None: #will be None until process terminates 
      with stopsignal.getlock(): #aquire rlock 
       stopsignal.value = 1 
      break 
    sleep(1) #only check every second
Verwandte Themen