Subprocess während eines Prozesses abbrechen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Deswegen kann man "os.kill" zumindest in seiner derzeitigen Semantik nicht plattformübergreifend implementieren, da etwas wie "os.kill(pid, 17)" unter Windows überhaupt nicht definiert ist.
Richtig, aber das muss es auch nicht. Wie man an ``subprocess.Popen.kill()`` sieht ist das unter Windows identisch mit ``subprocess.Popen.kill()``. Da trifft meiner Meinung nach Although practicality beats purity. aus dem Zen ein. Es spräche ja nichts dagegen unter Windows in ``os.kill`` nur die Signale 15 und 9 zuzulassen und beide ``TerminateProcess`` ausführen zu lassen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

Leonidas hat geschrieben:
lunar hat geschrieben:Deswegen kann man "os.kill" zumindest in seiner derzeitigen Semantik nicht plattformübergreifend implementieren, da etwas wie "os.kill(pid, 17)" unter Windows überhaupt nicht definiert ist.
Richtig, aber das muss es auch nicht. Wie man an ``subprocess.Popen.kill()`` sieht ist das unter Windows identisch mit ``subprocess.Popen.kill()``. Da trifft meiner Meinung nach Although practicality beats purity. aus dem Zen ein. Es spräche ja nichts dagegen unter Windows in ``os.kill`` nur die Signale 15 und 9 zuzulassen und beide ``TerminateProcess`` ausführen zu lassen.
Dagegen spräche imho, dass sich dem Semantik der Funktion dann zwischen beiden Systemen unterscheiden. Ich fände es besser, eine zweite Funktion "os.terminate(pid)" einzuführen, die speziell dafür da ist, plattformübergreifend Prozesse zu töten.

Allerdings ist diese Funktion ohne eine plattformübergreifende API zum Zugriff auf Prozessinformationen eher nutzlos, und angesichts der Unterschiede zwischen der Prozessverwaltung von Linux/Unix und Windows bezweifele ich, dass man eine solche API sinnvoll umsetzen kann.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Dagegen spräche imho, dass sich dem Semantik der Funktion dann zwischen beiden Systemen unterscheiden. Ich fände es besser, eine zweite Funktion "os.terminate(pid)" einzuführen, die speziell dafür da ist, plattformübergreifend Prozesse zu töten.
``subprocess.Popen.kill()`` unterscheidet sich jetzt schon von der Semantik unter den Systemen. Kleine semantische Unterschiede sind IMHO weniger störend als komplett fehlende Unterstützung von ähnlichen Features unter verschiedenen Platformen.

Die Prozessverwaltungen unterscheiden sich AFAIR sogar unter den Unices, also wäre es der Argumentation nach auch sinnlos ``os.kill()`` überhaupt bereitzustellen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

Leonidas hat geschrieben:Die Prozessverwaltungen unterscheiden sich AFAIR sogar unter den Unices, also wäre es der Argumentation nach auch sinnlos ``os.kill()`` überhaupt bereitzustellen.
kill(), die gebräuchlichen Signale und die Programme zur Prozessverwaltung (e.g. ps) sind POSIX-Standard. Die Prozessverwaltung läuft unter allen Unix-Derivaten weitgehend identisch, wenn man sich auf die Grundfunktionen beschränkt. Auf Sonderfunktionen wie /proc darf man sich natürlich nicht verlassen.

Die Prozessverwaltung von Windows fällt dagegen komplett aus dem Rahmen.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:kill(), die gebräuchlichen Signale und die Programme zur Prozessverwaltung (e.g. ps) sind POSIX-Standard.
Python bietet aber auch keine Unix-only Variante die Ausgabe von ``ps`` zu parsen, ebensowenig wie es dies für Windows bietet. Also muss man so oder so, auf platformspezifische Weise eine PID bekommen (sofern man den Subprocess nicht selbst gestartet hat, aber das wird inzwischen von ``subprocess`` abgedeckt) und nun muss man diese PID wiederrum auf platformspezifische Weise an eine Funktion zum Beenden weitergeben, weil ``os.kill()`` unbedingt die komplette POSIX-Semantik wiederspiegeln muss obwohl gleich daneben, in ``subprocess`` diese Semantik nicht streng eingehalten wird?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

Und wenn os.kill nicht die POSIX-Semantik wiederspiegeln soll, wie sollte es dann deiner Meinung nach aussehen? Windows kennt ja nicht mal PIDs.

Im Übrigen hat subprocess.Popen.kill genau gar nichts mit os.kill zu tun, wenn schon, dann wäre die entsprechende Funktion subprocess.Popen.send_signal.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Und wenn os.kill nicht die POSIX-Semantik wiederspiegeln soll, wie sollte es dann deiner Meinung nach aussehen? Windows kennt ja nicht mal PIDs.
Es soll eben für Betriebsysteme die es voll unterstützen das machen was es jetzt tut, auf anderen Systemen eben in dem Umfang wie es vom OS unterstützt wird. Also bei Windows eben ``TerminateProcess``.

Get process id from window handle, Process..::.Id Property, Finding the Process ID, Window-handle from process ID? und eine vage Erinnerung dass der Task-Manager von Windows XP eine Spalte für PIDs hatte, lassen mich meinen dass Windows durchaus PIDs hat.
lunar hat geschrieben:Im Übrigen hat subprocess.Popen.kill genau gar nichts mit os.kill zu tun, wenn schon, dann wäre die entsprechende Funktion subprocess.Popen.send_signal.
Es geht nicht um das Senden von Signalen sondern um das Terminieren von Applikationen. Natürlich ist erreicht man das Terminieren durch SIGTERM und SIGKILL, aber als User ist es mir *egal*. Ich will eine Applikation deren PID ich kenne beenden. Das geht unter Unices mit ``os.kill``, unter Windows nicht. Es wäre bereits genug wenn ``os.kill`` unter Windows nur SIGTERM/SIGKILL durch ``TerminateProcess`` unterstützen würde, das sind wohl auch unter Unix das Signal, das am häufigsten verwendet wird.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

Sorry, mir wird das blöd, denn deine Argumentation trifft geht an einer Wirklichkeit vorbei, in der man die PIDs des Prozesses, denn man töten möchte, bei der Programmierung nicht kennen kann, zugleich aber keine Möglichkeit hat, mit Bordmitteln unter Windows die PIDs bestimmter Prozesse herauszufinden. Woher soll diese PID denn kommen, die du da an os.kill weitergeben möchtest?

Ich bleibe dabei, dass kill() ohne eine vernünftige Möglichkeit, mit Bordmitteln Prozesse zu identifizieren, nutzlos ist. Unter Linux/Unix kann ich das mittels "ps", unter Windows gibt es nichts vergleichbares in allen Versionen.

Um Prozesse plattformübergreifend zu verwalten, wäre ein eigenes Modul dafür sinnvoll, dass ähnlich der .NET-Api eine abstrakte, objektorientierte Schnittstelle bietet. Einfach nur TerminateProcess in os.kill zu hacken, löst dagegen kein real existierendes Problem, aber bitte ... es steht dir frei, dass zu implementieren.

An einer weiteren Diskussion über den Sinn oder Unsinn von os.kill habe ich aber kein Interesse, denn Jens' Frage ist ja jetzt wohl mehr oder weniger beantwortet.

Im Übrigen existieren PIDs unter Windows zwar, entsprechend aber nicht den Linux PIDs, da man sie nicht direkt als Argument in der WinAPI einsetzen kann. Man benötigt immer zwangsläufig ein Handle auf den entsprechenden Prozess.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

lunar hat geschrieben:Ich bleibe dabei, dass kill() ohne eine vernünftige Möglichkeit, mit Bordmitteln Prozesse zu identifizieren, nutzlos ist. Unter Linux/Unix kann ich das mittels "ps", unter Windows gibt es nichts vergleichbares in allen Versionen.
Nein, aber Leute updaten und dann sind entsprechende Programme verfügbar. Oder man liefert eben sowas mit, bzw. hackt sich sowas selbst, evtl. mittels ctypes/pywin32. Aber dann muss man nur die Prozessinformation platformabhängig haben, das killen der Prozesse kann dann einheitlich geschehen. Ich ärgere mich lieber einmal mit der Win32-API als zweimal.

Ich habe keine Ahnung, warum du den Sinn nicht siehst *möglichst viel* auf verschiedenen Platformen unterstützen zu können.
lunar hat geschrieben:Im Übrigen existieren PIDs unter Windows zwar, entsprechend aber nicht den Linux PIDs, da man sie nicht direkt als Argument in der WinAPI einsetzen kann. Man benötigt immer zwangsläufig ein Handle auf den entsprechenden Prozess.
Was ja gar kein Problem ist, die zu bekommen. So gesehen kannst du PIDs als Kompatibilitätsabstraktion ansehen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

lunar hat geschrieben:Sorry, mir wird das blöd, denn deine Argumentation trifft geht an einer Wirklichkeit vorbei, in der man die PIDs des Prozesses, denn man töten möchte, bei der Programmierung nicht kennen kann, zugleich aber keine Möglichkeit hat, mit Bordmitteln unter Windows die PIDs bestimmter Prozesse herauszufinden. Woher soll diese PID denn kommen, die du da an os.kill weitergeben möchtest?
tasklist, pslist oder look here.
MFG
HWK
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

lunar hat geschrieben:Woher soll diese PID denn kommen, die du da an os.kill weitergeben möchtest?
Hm, übersehe ich jetzt etwas?

Code: Alles auswählen

p = subprocess.Popen(
    ["ping","-n","100","127.0.0.1"],
    shell=False
    )
print "PID:",p.pid
time.sleep(10)
print "terminate?"
p2= subprocess.Popen(
    ["taskkill","/PID",str(p.pid)],
    shell=True
    )
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

``shell=True`` ist wieder so eine Sache die man nach Möglichkeit vermeiden sollte.

Und ja, du hast die Diskussion falsch verstanden. Lunar und ich diskutierten darüber, wie man Prozesse beenden kann. Bei Prozessen die man selbst via ``subprocess.Popen`` startet geht das seit Python 2.6 mit ``terminate`` und ``kill``. Bei beliebigen Prozessen mit bekannter PID geht das nur unter Unix mit ``os.kill``, unter Windows gar nicht (das ist eben der Punkt den ich kritisiert habe und Lunar verteidigte) mit normalen Bordmitteln, geht nur mit ctypes, was zumindest seit Python 2.5 teil von Python ist. Lunars Argumentation war, dass man unter Windows keine Tools hat um die Prozesse und PIDs herauszulesen (es gibt ein paar, aber die gehören im Gegensatz zu ``ps`` nicht zum Standardumfang aller Windows-Versionen), man also sowieso nie in die Situation kommt, mit ``os.kill()`` Prozesse beenden zu wollen. Mein Punkt war, dass es durchaus Mittel und Wege gibt, auch unter Windows die PID herauszufinden. Soll jeder selbst entscheiden welcher Argumentation er eher zustimmt.

The real WTF ist aber, dass weder Lunar noch ich Windows überhaupt nutzen, somit betrifft das Problem eigentlich keinen von uns direkt :D
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

Qubit hat geschrieben:
jens hat geschrieben:
Qubit hat geschrieben:Aber schau dir mal die proctools von pycopia an ;-)
Sieht spontan nach linux-only aus ;)
Ups, ja.
Man sollte Windows abschaffen ;-)
wie schauts denn mit

import _subprocess
_subprocess.TerminateProcess(..)

aus?
Hat jemand damit unter Windows Erfahrung?
Okay, hatte etwas Zeit mich damit zu beschäftigen (Win Vista)
'2.5.1 (r251:54863) [MSC v.1310 32 bit (Intel)]'

Code: Alles auswählen

import subprocess, _subprocess

p = subprocess.Popen(
    ["ping","-n","100","127.0.0.1"],
    shell=False
    )
time.sleep(10)
print "terminate process:",p.pid
_subprocess.TerminateProcess(p._handle,1)
Antworten