Seite 1 von 1
2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 22. Februar 2024, 09:22
von Karl-Heinz Hofmann
Ich werde mit dem threading nicht schlau. Intensive Recherche im Net brachte auch nichts, dabei sollte das Problem simple zu bewerkstelligen sein.
So zum Thema:
Ich habe zwei Funktionen.
def viaexponent(n):
result = n**5
# hier sollte der Befehl stehen der "viamulti" killt
return result
def viamulti(n):
result = n*n*n*n*n
# hier sollte der Befehl stehen der "viaexponent" killt
return result
Im Hauptprogramm sollen beide simultan gestartet werden und je nachdem welche Funktion zuerst das Ergebnis hat, soll die andere Funktion aktiv stoppen.
Eigentlich ganz simpel. Hab einiges probiert. Und wie sähe der Aufruf im Hauptprogramm aus (mit Parameterübergabe)?
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 22. Februar 2024, 09:30
von __deets__
Das geht nicht. Threads kann man nicht killen. Du kannst es mit multiprocessing machen, die kann man abschiessen. Bei derart trivialen Berechnungen wird das aber natuerlich nix, weil die schneller fertig sind, als jedes Kommando zum abbrechen ankommen kann.
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 22. Februar 2024, 10:33
von Dennis89
Hallo,
je nach dem was der Sinn ist, vllt wäre es interessant die Ausführungszeit beider Funktionen zu messen und die dann zu vergleichen?
Grüße
Dennis
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 22. Februar 2024, 11:14
von Karl-Heinz Hofmann
Natürlich ist n**5 und n*n*n*n*n nur ein Platzhalter für in meinem Programm weitaus komplexere Funktion. Aus einem Pool von ca. 1000 n- Werte werden die Funktionen beschickt. Bei kleinen
n braucht Funktion A nur 0,5 Sekunden und B 50 Sekunden. Am Schluß, wenn n groß ist, ist es genau umgedreht. Soweit so gut könnte man in der Mitte einen Switchpoint setzen. Aber die Mitte der n Werte
liefert einmal 2 zu 30 Sekunden und der nächste n dann 20 zu 3 Sekunden z.B. Das geht dann für ca. 30 n so hin und her und schlecht vorherzusagen.
Eine Multiprocessing Lösung würde mich brennend interessieren. Bitte
Gruß Kalli
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 22. Februar 2024, 11:33
von grubenfox
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 22. Februar 2024, 12:40
von Karl-Heinz Hofmann
@grubenfox: Auf der Seite war ich schon. Find da aber nix passendes.
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 22. Februar 2024, 13:31
von __deets__
Also ich finde da
https://docs.python.org/3/library/multi ... .terminate oder auch kill, und das ist angesichts deines Vorhabens sehr passend.
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 22. Februar 2024, 23:16
von Sirius3
Threads und Multiprocessing arbeiten immer kooperativ. Das heißt, Du mußt in regelmäßigen Abständen abfragen, ob der andere Thread ein threading.Event gesendet hat, dass er fertig ist, und dann kann sich der eigene Thread auch beenden.
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Samstag 24. Februar 2024, 21:17
von Qubit
Mit futures.FIRST_COMPLETED sollte das auch funktionieren..
Code: Alles auswählen
from concurrent import futures
def viaexponent(n):
result = n**5
# hier sollte der Befehl stehen der "viamulti" killt
return result
def viamulti(n):
result = n*n*n*n*n
# hier sollte der Befehl stehen der "viaexponent" killt
return result
if __name__ == '__main__':
n=10000
with futures.ProcessPoolExecutor(max_workers=2) as e:
futs = {e.submit(func, n): func.__name__ for func in [viaexponent,viamulti]}
res = futures.wait(futs, return_when=futures.FIRST_COMPLETED)
for func in res.done:
print(f"{futs[func]}: {func.result()}")
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Samstag 24. Februar 2024, 21:34
von DeaD_EyE
Threads kann man killen und mache machen sich den Spaß das anderen zu zeigen, damit sie sich selbst ordentlich in den Fuß schießen können.
Wieso soll der Thread gekillt werden? Wieso kann das innerhalb der Funktion nicht durch Logik gelöst werden? Der Thread und/oder Prozess wird beendet, wenn die Funktion verlassen worden ist. Wenn du jetzt für das Problem Multiprocessing nutzt, hast du ein neues Problem: Serialisierung der Daten für den anderen Prozess.
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Mittwoch 28. Februar 2024, 00:35
von __blackjack__
@Qubit: Das bricht aber die anderen noch laufenden `Futures` an der Stelle nicht ab. Die werden trotzdem weiter berechnet.
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Mittwoch 28. Februar 2024, 14:20
von Qubit
__blackjack__ hat geschrieben: Mittwoch 28. Februar 2024, 00:35
@Qubit: Das bricht aber die anderen noch laufenden `Futures` an der Stelle nicht ab. Die werden trotzdem weiter berechnet.
Ja, das stimmt wohl.
Da hilft wohl dann nur, die Workerprozesse zu killen, wenn man das Future hat..
Code: Alles auswählen
from concurrent import futures
def viaexponent(n):
result = n**5
# hier sollte der Befehl stehen der "viamulti" killt
return result
def viamulti(n):
result = n*n*n*n*n
# hier sollte der Befehl stehen der "viaexponent" killt
return result
if __name__ == '__main__':
n=10000
e = futures.ProcessPoolExecutor(max_workers=2)
futs = {e.submit(func, n): func.__name__ for func in [viaexponent,viamulti]}
res = futures.wait(futs, return_when=futures.FIRST_COMPLETED)
for proc in e._processes:
e._processes[proc].kill()
e.shutdown()
for func in res.done:
print(f"{futs[func]}: {func.result()}")
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Mittwoch 28. Februar 2024, 14:25
von __blackjack__
@Qubit: Das ist nicht wirklich eine Lösung in die Interna von einer fremden Klasse einzugreifen. `_processes` kann existieren, muss es aber nicht. Die Objekte darin können eine `kill()`-Methode haben, müssen sie aber nicht. Wobei `terminate()` auch die freundlichere Wahl an der Stelle wäre.
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Mittwoch 28. Februar 2024, 14:41
von Qubit
__blackjack__ hat geschrieben: Mittwoch 28. Februar 2024, 14:25
Wobei `terminate()` auch die freundlichere Wahl an der Stelle wäre.
Ja, aber wohl mit einer Warnung..
https://docs.python.org/3/library/multi ... .terminate
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Mittwoch 28. Februar 2024, 16:15
von __deets__
Und beim kill gilt die gleiche Warnung, der Grund ist ja nun nicht das Signal an den Prozess, sondern der Zustand, der hinterlassen wird.
Re: 2 konkurierende Funktionen (Threading)
Verfasst: Donnerstag 29. Februar 2024, 12:21
von __blackjack__
Die Warnung steht wahrscheinlich bei `terminate()` weil man da im Gegensatz zum `kill()` noch die Chance hat beim anderen Prozess dieses Problem zu berücksichtigen, und im SIGTERM-Handler die Ressource freizugeben, während man beim `kill()` da ja wirklich nichts mehr machen kann.