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.
@Sirius3: In diesem Thread wird die Bedingung überprüft, die dazu führen kann, dass das Skript beendet werden muss. Die Überprüfung ist auch nicht auf den Haupt Prozess übertragbar.
@BlackJack: Es geht immer noch um das gleiche Projekt, zu dem ich schon mehrere Threads im Forum gestarte habe, also Situation:
Haupt Prozess zählt konstant etwas. Im Thread wird alle x Sekunden eine Datenbankverbindung aufgebaut und die Ergebnisse des Haupt Prozesses in die DB übertragen. Bei diesem Verbindungsufbau wird, falls ein Fehler auftritt, eine Email an den System Administrator geschickt und das gesamte Skript soll beendet werden. Ja theoretisch könnte ich nur den fehlerhaften Thread schließen, aber ich fände es angenehmer zu wissen, dass alles aus ist.
Eine Möglichkeit die ich mir überlegt habe ist, dass beim Start des Skriptes die Prozess-ID ermittelt und diese in den Thread mit übergeben wird. Sollte dann der Fehler auftreten, könnte ich das gesamte Skript über die Prozess-ID killen. Nur jetzt die Frage, ob das nicht auch einfacher geht?
Ist das ein so außergewöhnlicher Vorgang? Wenn ja, warum? ^^
mobby hat geschrieben:Ist das ein so außergewöhnlicher Vorgang? Wenn ja, warum? ^^
Nö, aber wahrscheinlich ist die Aufteilung deiner Threads etwas ungünstig. Der Hauptthread sollte sich eigentlich nur um die Verwaltung des Programms kümmern und die Aufgaben ggf. an andere Threads deligieren. Bei dir steckt im Hauptthread jedoch offenbar die ganze Logik. Daher würde ich aus dem Hauptthread einen Nebenthread machen, welcher ganz normal gestartet wird. Der Hauptthread kümmert sich dann nur um das Starten der Threads und nimmt anschließend Nachrichten von diesen entgegen.
@EyDu: Danke für den Hinweis, aber gehen wir jetzt mal davon aus, dass ich die Struktur nicht mehr abändern möchte. Daher mein Ansatz wie ich das lösen würde:
Ohne shell=True funzt schon mal gar nix und jetzt kommen bei der Abfrage 4 PIDs raus ... ich möchte aber nur die aktuelle des laufenden Skriptes was mach ich falsch?
//edit: Zudem habe ich dabei ein Problem mit Rechten ...
@mobby: das ist ja auch nicht der richtige Weg. Ein einfaches Flag, das vom Thread gesetzt wird und vom Hauptprogramm abgefragt wird, ist doch viel klarer und logischer, als dieses ganze Konstrukt, das Du da gerade zusammenschusterst.
mobby hat geschrieben:@EyDu: Danke für den Hinweis, aber gehen wir jetzt mal davon aus, dass ich die Struktur nicht mehr abändern möchte.
Warum willst du denn die Struktur deines Programms nicht mehr ändern? Wenn es halbwegs sauber programmiert ist, dann ist das doch eine total einfache Sache. Alles anderes ist doch nur eine Notlösung, welche dir früher oder später wohl um die Ohren fliegen wird.
Aber mal eine andere Sache: Du scheinst das subprocess-Modul nicht so richtig verstanden zu haben. Es gibt einen Grund, warum die ganzen Methoden als ersten Parameter eine Liste erwarten und warum der Wert des shell-Parameters per Default auf False gesetzt ist. Außerdem unterstüzt das subprocess-Modul ebenfalls Pipes, das solltest du alles nicht per Hand umsetzen. Lies dier doch besser noch einmal die Dokumentation dazu durch, du benutzt das Modul gerade so, wie es auf keinen Fall benutzt werden sollte. Um solche Dinge wie deine Aufrufe zu vermeiden wurde das subprocess-Modul überhaupt erst eingeführt.
Vielen Dank für die Rückmeldungen. Ich bin mir im klaren, dass ich da noch ziemlich viele Fehler mache und auch sicherlich einige Grundlagen fehlen. Ich bin dran das alles so langsam aufzuarbeiten. Da Python nur eine art Hobby von mir ist, habe ich leider nicht viel Zeit mich damit ausgiebig zu beschäftigen. Das hat dann solche Fails zur Folge ...
@Sirius3: Der Ansatz hört sich, so wie ich deine Aussage interpretiere, relativ einfach und logisch an. Nur wie mache ich das? Wenn ich nach Python und Flags suche, komme ich beim "argparse" Modul raus. Inwiefern ich das in meinem Beispiel anwenden kann, ist mir jedoch schleierhaft.
mobby hat geschrieben:@Sirius3: Der Ansatz hört sich, so wie ich deine Aussage interpretiere, relativ einfach und logisch an. Nur wie mache ich das? Wenn ich nach Python und Flags suche, komme ich beim "argparse" Modul raus. Inwiefern ich das in meinem Beispiel anwenden kann, ist mir jedoch schleierhaft.
Das ist keine Alternative zu der von mir beschriebenen Lösung, sondern ein Weg diese umzusetzen. Die dazu nötigen Elemente findest du im threading-Modul, du solltest dir dazu wirklich dringend die Dokumentation durchlesen. Wenn du mit Threads arbeitest, dann musst du das können. Sonst schießt du dir ganz schnell selbst in den Fuß. Ansonsten ist das queue-Modul noch sehr nützlich.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from threading import Thread
from threading import Lock
from time import sleep
class Status_check(object):
def __init__(self,value=False):
self.value = value
self.lock = Lock()
def set_status_kill(self):
with self.lock:
self.value = True
result = self.value
return result
def test(status):
print "Hallo ich bin der Thread"
sleep(10)
status.set_status_kill()
def start_thread(status):
thread = Thread(target=test, args=(status))
thread.setDaemon(True)
thread.start()
def main():
status = Status_check()
start_thread(status)
if status.set_status_kill() == True:
sys.exit()
while True:
print "hallo ich bin der Hauptprozess"
if __name__ == '__main__':
main()
Ist das von der Herangehensweise richtig oder lieg ich schon wieder voll daneben? Das es noch nicht funltioniert ist mir klar, denn wenn ich das ausprobiere killt er das Skript zwar, aber nicht zum gewünschten Zeitpunkt, sondern sofort KP warum ... lol
Bevor man die Pipes mittels der ``subprocess``-API umsetzt, kann man auch gleich die Anwendung von ``grep`` und ``awk`` mit Python-Mitteln ersetzen. Dann bleibt nur noch ``ps aux`` übrig. Rein theoretisch könnte man selbst dafür eine Lib einsetzen, falls es ein entsprechendes Python-Package gibt. Aber da würde ich auch verstehen, wenn man einfach bei dem ``subprocess``-Aufruf bleiben möchte.
@snafu: Der ganze Aufruf mit der Pipe ist Unsinn weil es dafür eine Funktion in der Standardbibliothek gibt, die nicht nur deutlich robuster funktioniert weil sie einfach die entsprechende POSIX C-Funktion aufruft um die eigene PID zu ermitteln, sondern auch auf System wo es ``ps``, ``grep``, oder ``awk`` nicht gibt. Das was da Prozess-ID genannt wird kann letztendlich deutlich mehr sein weil ``ps aux`` (zumindest unter Linux) auch die Kommandozeilenargumente zu jedem Prozess ausgibt, und das ``grep`` *alles* findet wo 'skriptname' in der Zeile enthalten ist. Unter anderen auch *sich selbst*. m)
Das ist, äh, suboptimal. Typischer Shell-Skripting-Hack den man öfter sieht, ist da noch ein ``| grep -v grep`` hinten dran zu hängen. Dann muss man aber sicher sein das das in der Zeile die man erwischen möchte garantiert nicht vorkommt, weder als Teilzeichenkette im Namen selbst, noch irgendwo in den Kommandozeilenargumenten.
@mobby:
Willst Du ernsthaft den Kontrollfluß über den Kernel steuern? Also ich ruf nicht beim Hausmeister an, ob er mal kurz den Strom abstellen könnte, nur weil die Waschmaschine noch an ist.