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.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Freitag 31. Oktober 2008, 15:53

ich kenne terminate nicht...

Aber ich denke der Aufbau ist eher so:

Code: Alles auswählen

myProcess = subprocess.Popen('test.exe')
myProcess.terminate()
Qubit
User
Beiträge: 75
Registriert: Dienstag 7. Oktober 2008, 09:07

Freitag 31. Oktober 2008, 16:46

azami1986 hat geschrieben:Hallo Leute,

wisst ihr vielleucht wie man einen Prozess, der mit subprocess gestartet wurde in python abbrechen kann? Gibt es einen Kill befehl oder ähnlich?
Hab in der API nichts gefunden...

Wäre sehr dankbar, wenn da jemand was wüsste... :-)
Standardmäßig nicht.
Aber schau dir mal die proctools von pycopia an ;-)
http://code.google.com/p/pycopia/source ... s.py?r=102
Benutzeravatar
jens
Moderator
Beiträge: 8482
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 31. Oktober 2008, 16:53

Qubit hat geschrieben:Aber schau dir mal die proctools von pycopia an ;-)
Sieht spontan nach linux-only aus ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Qubit
User
Beiträge: 75
Registriert: Dienstag 7. Oktober 2008, 09:07

Freitag 31. Oktober 2008, 17:00

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?
lunar

Samstag 1. November 2008, 00:22

jens hat geschrieben:os.kill() wird unter Windows nicht unterstützt. Warum eigentlich nicht?
Weil diese Funktionalität auf Windows-Systemen nicht existiert. "os.kill()" ist – trotz seines Namens – keine Funktion zum Töten von Prozessen, sondern lediglich zum Senden von Signalen. Man mittels os.kill auch ganz andere Dinge vollführen, wie z.B. per "os.kill(pid, signal.SIGUSR1)" Dienste dazu bewegen, ihre Konfiguration neu einzulesen oder per "os.kill(pid, signal.SIGSTOP)" Prozesse anhalten.

Zumindest ältere Windows-Systeme haben keine Entsprechung zu POSIX-Signalen, sondern kennen de facto lediglich das Abbrechen und das Töten von Prozessen. Unter Vista mag das anders sein, da wurde das POSIX-Subsystem imho deutlich erweitert.

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.

De facto ist die Behandlung von Prozessen auf Windows und auf POSIX-Systemen so unterschiedlich, dass eine einheitliche, plattformübergreifend identische Funktionalität kaum zu realisieren ist. Die meisten plattformübergreifenden Toolkits kennen deswegen eigentlich auch nur das Töten von Prozessen. Ein "os.terminate" wäre also der bessere Weg, das Töten von Prozessen zu implementieren.

Eigentlich halte ich es aber für sinnvoller, diese Dinge plattformspezifisch zu lösen, da die Unterschiede hier imho zu groß für eine einheitliche API sind. Das fängt ja schon damit an, dass es außer GUI-Programmen wie Firefox kaum plattformübergreifende Programme gibt, die auf beiden Systemen zuverlässig laufen. Desweiteren fehlt ja auch eine API, Prozesse zu identifizieren, ohne die eine Funktion zum Töten eher sinnlos wäre.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 1. November 2008, 09:35

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 Modvoice
lunar

Samstag 1. November 2008, 13:21

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
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 1. November 2008, 13:59

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 Modvoice
lunar

Samstag 1. November 2008, 14:17

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
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 1. November 2008, 17:50

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 Modvoice
lunar

Samstag 1. November 2008, 19:04

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
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 1. November 2008, 19:17

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 Modvoice
lunar

Samstag 1. November 2008, 19:41

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
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Samstag 1. November 2008, 19:50

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 Modvoice
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Samstag 1. November 2008, 21:55

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
Antworten