Seite 3 von 7
Re: Programm Kontrolle
Verfasst: Freitag 1. Juni 2012, 12:43
von Nobuddy
Hallo deets,
das mit dem UnboundLocalError:
Code: Alles auswählen
# Überprüfe ob ID aus pidpath aktuell ist
id_ok = False
try:
fobj = open('/tmp/check', "r")
for line in fobj:
if wert in line:
id_ok = True
fobj.close()
except UnboundLocalError:
pass
ist folgendes. in '/tmp/check', sind alle aktiven IDś des Users aufgeführt. Ist die gesuchte ID von 'wert' nicht darin enthalten, kommt es zu diesem Error.
Dies muß aber in dem Fall so sein, da wenn ich das Konstrukt so machen würde:
Code: Alles auswählen
# Überprüfe ob ID aus pidpath aktuell ist
fobj = open('/tmp/check', "r")
for line in fobj:
if wert in line:
id_ok = True
else:
id_ok = False
fobj.close()
würde ich keine konkrete richtige Ausgabe erhalten.
Nehmen wir einmal an, daß der ID-wert noch aktiv ist und sich daher auch in der Liste '/tmp/check' befindet, dann könnte z.B. mal die Ausgabe so
False
True
False
False
False
oder auch so
False
False
False
False
True
aussehen und ob dann letztendlich True oder False wirklich wahr ist, ist dann reine Glücksache.
Das mit denrace-conditions, habe ich mir mal im
http://de.wikipedia.org/wiki/Race_Condition angeschaut. Ich glaube, das lässt sich in einem ungünstigen Fall evtl. nicht ausschließen. Dazu müßte ich spezielle Tests durchführen, um zu sehen wie dann die Reaktion darauf ist.
Bestimmt lässt sich das noch eleganter und die Unschönheiten beseitigen, das werde ich auch als nächstes machen.
Freue mich immer über Tips und Verbesserungsvorschläge.

Re: Programm Kontrolle
Verfasst: Freitag 1. Juni 2012, 12:57
von deets
Das ist so natuerlich nicht richtig. Du kannst zb in dem Moment, wo du als erstes mal auf dein PID triffst die Schleife mit einem "break" verlassen. `
Oder benutzt gleich den in-operator....
Als kleiner Hinweis: *NIEMALS* ist es notwendig, einen UnboundLocalError wirklich selbst zu behandeln. Dann hast du immer einen Programmierfehler/Denkfehler gemacht.
Und was die Tipps angeht - die wurden dir hier schon diverse male gebeben: benutze eine lockfile. puntk. bzw. die von Leonidas angegebenen Moeglichkeiten via dbus & Co. Das warst du machst ist gewurschtel.
Re: Programm Kontrolle
Verfasst: Freitag 1. Juni 2012, 14:34
von Nobuddy
deets, Danke für Deinen break-Tipp, jetzt benötige ich den UnboundLocalError nicht mehr.
Ich werde mich weiter mit den schon gemachten Vorschlägen, wie lockfile und dbus und Co. befassen.
Da tue ich mich momentan noch schwer, da diese Wissen mir noch fehlt.
Ich habe zu dbus hier
http://www.documentroot.net/linux/python-dbus-tutorial mal was gefunden, das ich durcharbeiten werde.
Nach gewissen Änderungen, ist der aktuelle Stand meines Konstrukt so:
Code: Alles auswählen
TITEL = 'Lieferanten-Bestellungen'
# Programm
def auftrag():
from bestellorder_lieferant import auftragkontrolle
auftragkontrolle()
class DialogFenster(tkSimpleDialog.Dialog):
def foo():
'''
Das Dialog-Fenster besteht aus den Dialogen "ok" und "cancel".
Die weitere Beschreibung über die Rolle und Funktionalität,
muß noch erarbeitet werden.
'''
def body(self, master):
self.title(TITEL)
self.auftraginfo = 'Programm für %s starten?' % TITEL
self.namen = Label(master, text=self.auftraginfo)
self.namen.pack(side=LEFT)
def apply(self):
self.result = True
return
def start_bestellorder(title):
def foo():
'''
Haupt- und Einstiegsfunktion der Auftragsabwicklung. Sie startet einen
Dialog, in dem das Paket "bestellorder_lieferant" gestartet werden kann.
:param TITEL: string mit dem Titel des Dialogfensters
:param AUFTRAGINFO: string mit Informationen zum Auftrag
'''
NamenDialog = DialogFenster(Tk())
# Liste Dateien aus pidpath_path auf
exist = os.listdir(pidpath_path)
# Überprüfe pidpath in Liste
if pidpath in exist:
fobj = open('/tmp/%s' % pidpath, "r")
for line in fobj:
wert = line
fobj.close()
# Erstelle Datei über aktive IDś
os.system('ps -u $USER > /tmp/check 2>/dev/null')
# Überprüfe ob ID aus pidpath aktuell ist
id_ok = False
try:
fobj = open('/tmp/check', "r")
for line in fobj:
if wert in line:
id_ok = True
fobj.close()
except UnboundLocalError:
pass
# ID ist aktuell, Abbruch
if id_ok == True:
print "Programm läuft schon mit PID:", wert
sys.exit(1)
# ID ist nicht aktuell, pidpath wird gelöscht
if id_ok == False:
try:
os.remove('/tmp/%s' % pidpath)
except OSError:
pass
try:
if NamenDialog.result == True:
exist = auftrag().os.getpid()
fobj = open('/tmp/%s' % pidpath, 'w')
fobj.write(str(exist))
fobj.close()
else:
info = 'Der Programmstart für %s wurde abgebrochen!' % title
except (ImportError, OSError):
info = 'Es gab einen Fehler, das Programm für %s konnte nicht gestartet werden!' % title
tkMessageBox.showinfo('Info', info)
Tk().destroy()
if __name__ == "__main__":
start_bestellorder(TITEL)
Re: Programm Kontrolle
Verfasst: Freitag 1. Juni 2012, 16:22
von deets
Du hast das UnboundLocalError aber immer noch drin...
Und "if a == True" schreibt man einfach "if a", analog "if a == False" einfach als "if not a". Ausserdem solltest du nicht os.system, sondern subprocess benutzen (os.system funktioniert, aber mit subprocess zB kannst du ganz ohne temporaere datei auskommen, und es sollte wegen der besseren moeglichkeiten generell vorgezogen werden).
schreibt man stattdessen
Und
Code: Alles auswählen
with open('/tmp/check') as inf:
id_ok = wert in inf.readlines()
sollte auch reichen, statt dieses riesen try/open/for/close/except-Konstrukts.
Re: Programm Kontrolle
Verfasst: Freitag 1. Juni 2012, 16:44
von BlackJack
@deets: Das `readlines()` kann man auch noch weglassen.
Allerdings würde ich gar kein externes Programm aufrufen, sondern lieber `psutil` installieren und `psutil.pid_exists()` verwenden oder ein `psutil.Process()`-Exemplar erstellen, denn dann kann man auch noch prüfen ob zu der PID das richtige Programm gehört.
Re: Programm Kontrolle
Verfasst: Samstag 2. Juni 2012, 14:02
von Nobuddy
Hallo deets,
Danke für Deine Info.
Das mit 'id_ok = wert in inf.readlines()' (auch ohne '.readlines()') bringt nicht das gewünschte Ergebnis.
Ein paar Dinge habe ich an meinem Konstrukt geändert und sieht nun so aus:
Code: Alles auswählen
TITEL = 'Lieferanten-Bestellungen'
class DialogFenster(tkSimpleDialog.Dialog):
def foo():
'''
Das Dialog-Fenster besteht aus den Dialogen "ok" und "cancel".
Die weitere Beschreibung über die Rolle und Funktionalität,
muß noch erarbeitet werden.
'''
def body(self, master):
self.title(TITEL)
self.auftraginfo = 'Programm für %s starten?' % TITEL
self.namen = Label(master, text=self.auftraginfo)
self.namen.pack(side=LEFT)
def apply(self):
self.result = True
return
# Programmaufruf
def auftrag():
from bestellorder_lieferant import auftragkontrolle
auftragkontrolle()
def start_bestellorder(title):
def foo():
'''
Haupt- und Einstiegsfunktion der Auftragsabwicklung. Sie startet einen
Dialog, in dem das Paket "bestellorder_lieferant" gestartet werden kann.
:param TITEL: string mit dem Titel des Dialogfensters
:param AUFTRAGINFO: string mit Informationen zum Auftrag
'''
NamenDialog = DialogFenster(Tk())
# Liste Dateien aus pidpath_path auf
exist = os.listdir(pidpath_path)
# Überprüfe pidpath in Liste
if pidpath in exist:
with open('/tmp/%s' % pidpath,'r') as inf:
for line in inf:
wert = line
else:
wert = 'not_id'
# Erstelle Datei über aktive IDś
os.system('ps -u > /tmp/id_check 2>/dev/null')
# Überprüfe ob ID aus pidpath aktuell ist
with open('/tmp/id_check','r') as inf:
for i in inf:
if wert in i:
id_ok = True
break
else:
id_ok = False
# Abbruch, wenn ID aktuell
# pidpath löschen, wenn ID nicht aktuell
if id_ok:
info = 'Programm läuft schon mit PID: %s' % wert
tkMessageBox.showinfo('Info', info)
Tk().destroy()
sys.exit(1)
else:
try:
os.remove('/tmp/%s' % pidpath)
except OSError:
pass
try:
if NamenDialog.result:
exist = os.getpid()
with open('/tmp/%s' % pidpath,'w') as inf:
inf.write(str(exist))
auftrag()
else:
info = 'Der Programmstart für %s wurde abgebrochen!' % title
except (ImportError, OSError):
info = 'Es gab einen Fehler, das Programm für %s konnte nicht gestartet werden!' % title
tkMessageBox.showinfo('Info', info)
Tk().destroy()
if __name__ == "__main__":
start_bestellorder(TITEL)
Jetz schaue ich noch, wie ich 'subprocess' integriert bekomme.
Mit dbus und Co. muß ich mich erst noch einarbeiten.
Re: Programm Kontrolle
Verfasst: Sonntag 3. Juni 2012, 18:53
von Nobuddy
subprocess, habe ich so integriert:
Was mich etwas stört, ist daß jedes mal wenn sich das Programm 'auftrag()' mit einem Fenster (tkinter) meldet, bleibt am Ende immer ein weiteres Unterfenster von 'tk', 'tk #2', 'tk #3' usw. bestehen. Dies ist ja besonderst störend, wenn sich das Programm häufig meldet und es dann einen Haufen offener tk-Fenster gibt.
Ich meine nicht die Fenster, die mir irgendwelche Informationen ausgeben, sondern diese tk-Fenster sind leer.
Gibt es da eine Möglichkeit, dieses Phänomen auszuschalten?
Re: Programm Kontrolle
Verfasst: Montag 4. Juni 2012, 01:59
von Leonidas
Nobuddy hat geschrieben:Gibt es da eine Möglichkeit, dieses Phänomen auszuschalten?
Keine weiteren Fenster aufzumachen scheint mir die einfachste Lösung zu sein.
Re: Programm Kontrolle
Verfasst: Montag 4. Juni 2012, 09:24
von Nobuddy
Leonidas hat geschrieben:Nobuddy hat geschrieben:Gibt es da eine Möglichkeit, dieses Phänomen auszuschalten?
Keine weiteren Fenster aufzumachen scheint mir die einfachste Lösung zu sein.
Ok, und würdest Du mir diese Lösung verraten?
Re: Programm Kontrolle
Verfasst: Montag 4. Juni 2012, 12:22
von Leonidas
In ``auftragkontrolle()`` keine weiteren ``Tk``-Instanzen erzeugen.
Re: Programm Kontrolle
Verfasst: Montag 4. Juni 2012, 12:45
von Nobuddy
Einfacher gesagt als getan.
Ich verwende zum Starten von bestellorder_lieferant.py in dem dann auftragkontrolle() läuft, start_bestellorder.py.
In start_bestellorder.py verwende ich 'Tk', das ich zur Steuerung und Informationsausgabe nutze.
Weiter nutze ich auch 'Tk' in bestellorder_lieferant.py (auftragkontrolle()) zur Steuerung und Informationsausgabe.
Wie kann ich das schaffen, um keine weiteren `Tk``-Instanzen zu erzeugen?
Re: Programm Kontrolle
Verfasst: Montag 4. Juni 2012, 12:48
von Hyperion
Nobuddy hat geschrieben:
Wie kann ich das schaffen, um keine weiteren `Tk``-Instanzen zu erzeugen?
Stichwort: Parameterübergabe!

Re: Programm Kontrolle
Verfasst: Montag 4. Juni 2012, 13:54
von Nobuddy
Hyperion hat geschrieben:Nobuddy hat geschrieben:
Wie kann ich das schaffen, um keine weiteren `Tk``-Instanzen zu erzeugen?
Stichwort: Parameterübergabe!

Vom Starter zum Programm?
Welche Parameter?
Vielleicht hast Du mir auch noch ein zweites Stichwort?
Re: Programm Kontrolle
Verfasst: Montag 4. Juni 2012, 14:12
von Hyperion
Du hast doch offensichtlich verschiedene Funktionen, in denen so etwas in der Art steht:
Anstelle immer neue Tk-Instanzen zu erstellen, übergebe diese doch der entsprechenden Funktion:
Code: Alles auswählen
def demo_func(param1, param2, ..., root) # <- `root` ist neu!
# irgend welcher Code
# folgende Zeile auskommentieren
# root = Tk()
# irgend welcher Code
another_gui_func(param1, param2, ..., root) # <- wir "schleifen" `root` durch!
Damit musst Du nun ein Tk-Objekt übergeben. Dieses wird dann aber eben außerhalb der Funktion erstellt und kann über zig Funktionen hinweg durchgeschleift werden. Du musst das dann noch ggf. als neuen Parameter hinzufügen.
Damit Du aber die Funktionen ggf. auch separat aufrufen kannst, könntest Du das ganze noch ein wenig flexibilisieren:
Code: Alles auswählen
def demo_func(param1, param2, ..., root=None) # <- `root` wird nun "optional"
# wenn es noch kein root-Objekt gibt, legen wir es hier an.
if root is None:
root = Tk()
# irgend welcher Code
Irgend wie habe ich dennoch die ungute Idee, dass Du zu viel Logik mit GUI mischst... mir ist da noch nicht klar, wieso Du über zig Module hinweg augenscheinlich GUI-Funktionalität hast.
Aber ehrlich gesagt habe ich eh längst den Überblick über Dein Projekt verloren bzw. hatte es nie

Re: Programm Kontrolle
Verfasst: Mittwoch 6. Juni 2012, 08:51
von Nobuddy
Hallo Hyperion,
Danke für Deinen Input!
Ich habe da lange herum experimentiert, bekam Deinen Lösungsansatz leider nicht so umgesetzt.
Heute habe ich dann eine Lösung gefunden.
GUI-Modul:
Code: Alles auswählen
from Tkinter import *
import tkSimpleDialog, tkMessageBox
# Programm
TITEL = ''
AUFTRAGINFO = ''
dialog_result = set()
def dialog_func(title, info, root=None): # <- `root` wird nun "optional"
# wenn es noch kein root-Objekt gibt, legen wir es hier an.
if root is None:
root = Tk()
DialogFenster = tkMessageBox.askquestion(title, info)
root.destroy()
global result
if DialogFenster == 'yes':
result = True
elif DialogFenster == 'no':
result = False
dialog_result.add(result)
def info_func(title, info, root=None): # <- `root` wird nun "optional"
# wenn es noch kein root-Objekt gibt, legen wir es hier an.
if root is None:
root = Tk()
tkMessageBox.showinfo(title, info)
root.destroy()
if __name__ == "__main__":
dialog_func(TITEL, AUFTRAGINFO)
info_func(TITEL, AUFTRAGINFO)
Wobei ich glaube, daß hier 'if __name ...' überflüssig ist, bzw. ich falsch anwende.
Work-Modul:
Code: Alles auswählen
from a import dialog_result, dialog_func, info_func
TITEL = 'Lieferanten-Bestellungen'
AUFTRAGINFO = 'Programm für %s starten?' % TITEL
dialog_func(TITEL, AUFTRAGINFO, root=None)
if dialog_result:
if True in dialog_result:
result = True
elif False in dialog_result:
result = False
if result:
info = 'Es funktioniert.'
info_func(TITEL, info, root=None)
else:
info = 'Abbruch'
info_func(TITEL, info, root=None)
Es funktioniert fehlerfrei, wobei ich mir nicht sicher bin, welche Fehler ich hier doch gemacht habe.
Würde mich freuen, wenn Ihr mir die Fehler aufzeigt.
Bitte seit etwas nachsichtig dabei.

Re: Programm Kontrolle
Verfasst: Mittwoch 6. Juni 2012, 09:46
von Hyperion
Also ehrlich gesagt frage ich mich, was an meinem Vorschlag so schwierig war? Evtl. liegt es daran, dass ich aufgrund Deines jetzt gezeigten Code überhaupt nicht kapiere, wie das Problem überhaupt auftreten konnte! So weit ich das sehe, kommt es ja niemals vor, dass ein Tk-Objekt mehrfach erzeugt wird, ohne dass es danach wieder "zertsört" wird... insofern zweifle ich das gesamte Problem an.
Davon abgesehen, hast Du meine Idee auch nicht verstanden fürchte ich. Denn das `if` hättest Du Dir komplett sparen können - versuch doch mal eine Funktion mit einem Tk-Objekt aufzurufen
Meine "inline" Kommentare solltest Du nicht übernehmen; das macht man in Python nicht. Ich habe das nur so markiert, damit Dir beim Angucken des Beispiels klar wird, was ich da mache.
Ich gehe irgend wie davon aus, dass Dir immer noch nicht wirklich klar ist, wie "Namen" in Python funktionieren, also in welchem Bereich sie "gültig" bzw. an ein spezielles Objekt gebunden sind, wie Parameter funktionieren und wie Rückgabewerte. Denn ich sehe da schon wieder ein global und eine Funktion mit dieser Signatur mit `root=None` aufzurufen macht wirklich keinen Sinn!
Des Weiteren hast Du den "main"-Hook in Deinem "work"-Modul ja wieder vollkommen über Bord geworfen... also hast Du den Sinn davon wohl auch noch nicht verstanden.
Dir fehlt es einfach an zu vielen Baustellen... damit scheint mir Dein aktuelles Projekt fast schon zu groß und komplex zu sein. Du müsstest viel konsequenter versuchen, wirklich jede Code-Zeile zu durchdenken und nachzuvollziehen, wieso das da so steht. Dann würden solche "Patzer" wie der so semantisch sinnlose Code-Block *in* den `if`-Statements nicht passieren. (Meine Beispiele sind semantisch *sinnvoll* eingerückt!)
Du scheinst Code-Schnipsel oder Prinzipien auch nicht in einer Shell zu testen! Das ändern wir jetzt mal:
Probiere bitte folgendes aus: Tippe diesen Code mal in eine Python-Shell und führe ihn nacheinander aus und schaue Dir an, was als Ausgabe kommt (ggf. auch Fehlermeldungen) und versuche zu verstehen, wieso das der Fall ist.
Code: Alles auswählen
def get_greeting():
return "Hello, World"
name = get_greeting()
print name
Code: Alles auswählen
def get_greeting(name):
return "Hello, %s" % name
name = get_greeting()
name = get_greeting("World")
print name
Code: Alles auswählen
def get_greeting(name="World"):
return "Hello, %s" % name
print get_greeting()
So, ich hoffe das deckt die wesentlichen Fragen erst einmal ab

Also probiere es Schritt für Schritt aus und versuche Dir klar zu machen, was da *genau* passiert. Danach solltest Du Dir erklären können, wieso Dein Aufruf mit `root=None` überflüssig ist und wieso die "main"-Funktion im GUI-Modul "nichts" (sichtbares) tut.
Re: Programm Kontrolle
Verfasst: Mittwoch 6. Juni 2012, 17:23
von Nobuddy
Hallo Hyperion,
Deinen letzten Vorschlag habe ich leider nicht verstanden, auch wenn ich ich Deinen Post viele male durchgegangen bin. Daher habe ich auch `root=None` nicht richtig eingesetzt.
Deine Inline-Kommentare habe ich nur beim Testen mit übernommen, sind jetzt verschwunden.
Das mit den Namen und Gültigkeitsbereichen, ob global oder nicht, dies bereitet mir in der tat noch manchmal Probleme.
Das mit dem "main"-Hook, ist doch dazu gedacht, wenn ich das Modul direkt aufrufe, oder?
Das mit den `if`-Statements habe ich korrigiert, soweit wir das Gleiche meinen. ich poste am Schluß nochmals das Beispiel-Konstrukt.
Wenn es als problematisch wird, teste ich die Code-Schnipsel als separat in Geany. Manchmal auch direkt auf der Konsole.
Deinen Code habe ich durch gemacht, Danke dafür.
Die zwei Beispiel-Konstrukte, habe ich jetzt so geändert.
GUI-Modul:
Code: Alles auswählen
from Tkinter import *
import tkMessageBox
dialog_result = set()
def dialog_func(title, info):
root = Tk()
DialogFenster = tkMessageBox.askquestion(title, info)
root.destroy()
dialog_result.clear() # Liste leeren
if DialogFenster == 'yes':
result = True
elif DialogFenster == 'no':
result = False
dialog_result.add(result)
def info_func(title, info):
root = Tk()
tkMessageBox.showinfo(title, info)
root.destroy()
und das Work-Modul:
Code: Alles auswählen
from GUI-Modul import dialog_result, dialog_func, info_func
TITEL = 'Lieferanten-Bestellungen'
AUFTRAGINFO = 'Programm für %s starten?' % TITEL
dialog_func(TITEL, AUFTRAGINFO)
if True in dialog_result:
info = 'Es funktioniert.'
info_func(TITEL, info)
elif False in dialog_result:
info = 'Abbruch'
info_func(TITEL, info)
Sorry, ist wahrscheinlich nicht das, was Du mir mit Deinem Vorschlag vermitteln wolltest. Ich weiß, da fließt noch viel Wasser den Rhein hinuter ...
Funktionieren tut es jedenfalls.
Im GUI-Modul habe ich ja dies 'dialog_result.clear()' eingebaut, da ich ja über einer Startkontrolle das eigentliche Modul starte und dann in die Liste 'dialog_result' natürlich True enthält, was bei weiteren Fenster-Dialogen sonst zu falschen Resultaten führen kann.
Re: Programm Kontrolle
Verfasst: Mittwoch 6. Juni 2012, 17:34
von Hyperion
Nobuddy hat geschrieben:
Deinen Code habe ich durch gemacht, Danke dafür.
Hast Du denn nun verstanden, wieso der Aufruf mit `root=None` unnötig war? Und wieso das mit dem `if` anders gedacht war?
Re: Programm Kontrolle
Verfasst: Mittwoch 6. Juni 2012, 18:27
von Nobuddy
Hyperion hat geschrieben:Nobuddy hat geschrieben:
Deinen Code habe ich durch gemacht, Danke dafür.
Hast Du denn nun verstanden, wieso der Aufruf mit `root=None` unnötig war? Und wieso das mit dem `if` anders gedacht war?
Ich habe `root=None` nicht so genutzt, wie von Dir angedacht. Das 'if' in Deinem Vorschlag, war ja in Verbindung mit `root=None`, wenn ich das richtig ist.
Ich habe leider Deinen Vorschlag nicht verstanden und das mit `root=None` und 'if' in Deinem Vorschlag, da tappe ich noch immer im Dunkeln, oder stehe vielleicht auf der Leitung, sorry!
Sind die zwei Beispiel-Konstrukte halbwegs für Dich akzeptabel?
Re: Programm Kontrolle
Verfasst: Mittwoch 13. Juni 2012, 09:31
von Nobuddy
So, nach dem ich mich einige Tage nicht gemeldet habe, möchte ich Euch heute, mein Modul zur Programm-Kontrolle vorstellen. Leider konnte ich das mit 'dbus' noch nicht umsetzen.
Folgender Ablauf, wird in dem Modul prog_check.py umgesetzt, das in dem Auftrags-Modul integriert ist:
- Übergabe der aktuellen PID des Auftrags-Modul
- Überprüfung, ob das Auftrags-Modul evtl. schon läuft
- Freigabe des Auftrags-Modul, wenn kein Doppelstart vorliegt
- Auswahldialog bei Doppelstart
-- Auswahlmöglichkeit Abbruch (Nein), schon gestartetes Auftrags-Modul läuft weiter
-- Auswahlmöglichkeit Beenden (Ja), schon gestartetes Auftrags-Modul wird beendet
prog_check.py:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
### Import Module
import os, re
from gui_dialog import dialog_result, dialog_func, showinfo_func
# Programmaufruf
class prog_control(object):
def description():
'''
Kontrollfunktion für Start von Programmen.
- Übergabe der aktuellen PID des Auftrags-Modul
- Überprüfung, ob das Auftrags-Modul evtl. schon läuft
- Freigabe des Auftrags-Modul, wenn kein Doppelstart vorliegt
- Auswahldialog bei Doppelstart
-- Auswahlmöglichkeit Abbruch (Nein), schon gestartetes Auftrags-Modul läuft weiter
-- Auswahlmöglichkeit Beenden (Ja), schon gestartetes Auftrags-Modul wird beendet
Bei schon gestartetem Programm, wird ein nochmaliges starten
des gleichen Programmes verhindert. Gleichzeitig wird ein
Dialog zum Beenden des aktiven Programmes angeboten.
:param programm: string, Programmnamen
:param titel: string, Programm-Bezeichnung
:param pid_current: int, aktuelle PID des gestarteten Programmes
'''
def __init__(self, programm, titel, pid_current):
self.programm = programm
self.titel = titel
self.pid_current = pid_current
# Die ersten 15 Stellen des Programmnamens
self.prog_short = '{}'.format(self.programm[:15])
self.prog_pid = ''
self.pid_ok = False
self.pid_diff = 0
def prog_list(self):
# Erstelle Datei über aktive IDś
os.system('ps -u $USER > /tmp/id_check 2>/dev/null')
os.system('ps -u > /tmp/id_check2 2>/dev/null')
def prog_check(self):
# Überprüfe ob ID aus pidpath aktuell ist
with open('/tmp/id_check','r') as inf:
for i in inf:
if self.prog_short in i:
line = re.sub('^[ ]+', '', i)
self.prog_pid = line.partition(' ')[0]
self.pid_ok = True
break
if not self.pid_ok:
with open('/tmp/id_check2','r') as inf:
for i in inf:
if self.programm in i:
line = re.sub('[ ]+', '-', i)
self.prog_pid = line.partition('-')[2]
self.prog_pid = self.prog_pid.partition('-')[0]
self.pid_ok = True
break
else:
self.pid_ok = False
if self.prog_pid is not None and self.pid_current is not None:
self.pid_diff = (int(self.prog_pid) - int(self.pid_current))
else:
self.pid_diff = 1
def prog_evaluation(self):
# Programmstart, wenn Programm nicht schon läuft.
# Bei schon laufendem Programm, erfolgt ein
# Dialog über Abbruch oder Programmende des schon laufenden
# Programmes. So besteht die Möglichkeit, bei nochmaligen
# Starten des Programmes, das laufende Programm zu beenden.
if self.pid_ok is True and self.pid_diff is not 0:
info = '''Programm läuft schon mit PID: %s
Möchten Sie dieses Programm beenden?''' % self.prog_pid
dialog_result.clear()
dialog_func(self.titel, info)
if True in dialog_result:
os.kill(int(self.prog_pid), signal.SIGTERM)
os.kill(int(self.pid_current), signal.SIGTERM)
info = 'Programm mit PID: %s wird beendet' % self.prog_pid
showinfo_func(self.titel, info)
sys.exit(1)
else:
os.kill(int(self.pid_current), signal.SIGTERM)
sys.exit(1)
else:
try:
pass
except OSError:
pass
if __name__ == "__main__":
f = prog_control(programm, titel, pid_current)
f.prog_list()
f.prog_check()
f.prog_evaluation()
Auftrag-Modul (Teilausschnitt, wo prog_check.py integriert ist):
Code: Alles auswählen
PROGRAMM = 'bestellorder_lieferant.py'
TITEL = 'Lieferanten-Bestellungen'
AUFTRAGINFO = 'Programm für %s starten?' % TITEL
### Programm ###
def start_bestellorder():
def start_description():
'''
Einstiegs- und Kontrollfunktion der Auftragsabwicklung.
Ziel dieser Funktion, ist das kontrollierte Starten des Moduls
"bestellorder_lieferant.py". Die Kontrollfunktion wird durch das
Modul "prog_check.py" gesteuert.
Folgende Parameter werden dazu benötigt:
:param PROGRAMM: string, Programmnamen
:param TITEL: string, Programm-Bezeichnung
:param pid_current: int, aktuelle PID des gestarteten Programmes
'''
# PID für dieses gestartete Modul
pid_current = os.getpid()
#Kontrollmodul in der startphase
def prog_check(PROGRAMM, TITEL, pid_current):
f = prog_control(PROGRAMM, TITEL, pid_current)
f.prog_list()
f.prog_check()
f.prog_evaluation()
prog_check(PROGRAMM, TITEL, pid_current)
# Dialog-Fenster
# Start oder Abbruch
dialog_func(TITEL, AUFTRAGINFO)
try:
if True in dialog_result:
pass
elif False in dialog_result:
info = 'Der Programmstart für %s wurde abgebrochen!' % TITEL
showinfo_func(TITEL, info)
sys.exit(1)
except (ImportError, OSError):
info = 'Es gab einen Fehler, das Programm für %s konnte nicht gestartet werden!' % TITEL
showinfo_func(TITEL, info)
... hier folgt dann der Haupt-Code für die Auftragsverwaltung.
Ich hoffe, daß ich hier nicht mehr so viele Fehler gemacht habe.
Freue mich über Eure Kritikpunkte und Verbesserungsvorschläge.
Grüße Nobuddy