hi,
ich habe eine frage zu signal handlern. ich möchte ein signalhandler installieren, mein programm besteht aus 2 prozessen (erzeugt per fork),und einer dieser Prozesse erzeugt 2 threads per threading.thread.
kann mir jemand sagen wo ich die signalhandler einsetzen muss ? habe schon jede menge eperiementiert, aber leider komme ich net zurecht..
mfg
Mauser
Prozesse / Threads und signal
Einsetzen damit das Signal gehandelt wird?
Welches Signal? Manche können nicht geblockt werden (kill -9 )
Die einfache Lösung wäre den SignalHandler im Haupthread zu installieren --- also bevor Dein Programm überhapt multithreaded wird. Außerdem ist IMHO der Thread in dem dann der SignalHandler im Falle einer Auslösung läuft nicht festgelegt.
Der Handler bekommt Stackframe etc. als Parameter.
cu beyond
Welches Signal? Manche können nicht geblockt werden (kill -9 )
Die einfache Lösung wäre den SignalHandler im Haupthread zu installieren --- also bevor Dein Programm überhapt multithreaded wird. Außerdem ist IMHO der Thread in dem dann der SignalHandler im Falle einer Auslösung läuft nicht festgelegt.
Der Handler bekommt Stackframe etc. als Parameter.
cu beyond
hi,
ich hatte den signalhandler für SIGTERM am anfang meines progs installiert. mittlerweile bin ich darauf gelommen, dass mein problem bei einem aufruf von waitpid liegt.
folgendes szenario:
ein thread lässt in einer endlosschleife einen mp3player laufen, wartet bis sich dieser beendet hat (nachdem er einen song gespielt hat) und startet ihn neu, mit einem neuen song. solange os.waitpid(mp3player.pid) aktiv ist, wird das signal nicht bearbeitet.
gibt es da wohl eine andere möglichkeit, auf die beendigung des prozesses zu warten, so dass der signalhandler nicht blockiert wird und ich erkennen kann, wann der prozess endet ?
ich hoffe ich wurde verstanden
mfg
mauser
ich hatte den signalhandler für SIGTERM am anfang meines progs installiert. mittlerweile bin ich darauf gelommen, dass mein problem bei einem aufruf von waitpid liegt.
folgendes szenario:
ein thread lässt in einer endlosschleife einen mp3player laufen, wartet bis sich dieser beendet hat (nachdem er einen song gespielt hat) und startet ihn neu, mit einem neuen song. solange os.waitpid(mp3player.pid) aktiv ist, wird das signal nicht bearbeitet.
gibt es da wohl eine andere möglichkeit, auf die beendigung des prozesses zu warten, so dass der signalhandler nicht blockiert wird und ich erkennen kann, wann der prozess endet ?
ich hoffe ich wurde verstanden
mfg
mauser
Interessant! Klar solange das Programm "im waitpid" ist wird es sleeping o.ä. sein und keine Signals handeln.
Was passiert bei os.system oder einem Aufruf der das Programm nicht blockiert?
Bei 2. Lösung muß man dann immer prüfen, ob das MP3-Player-Programm noch läuft d.h. PID noch da und noch zu dem Programm gehörend. (sleep(1.23) nicht vergessen sonst frisst es CPU-Leistung).
Bin gespannt ob es so läuft ...
Da fällt mir noch ein: Du konntest Dein Hauptprogramm auch forken anstatt multithreading ...
cu beyond
Was passiert bei os.system oder einem Aufruf der das Programm nicht blockiert?
Bei 2. Lösung muß man dann immer prüfen, ob das MP3-Player-Programm noch läuft d.h. PID noch da und noch zu dem Programm gehörend. (sleep(1.23) nicht vergessen sonst frisst es CPU-Leistung).
Bin gespannt ob es so läuft ...
Da fällt mir noch ein: Du konntest Dein Hauptprogramm auch forken anstatt multithreading ...
cu beyond
hi,
mittlerweile habe ich bei mir tiefere fehler entdeckt, es liegt also nicht (nur) an os.waitpid.
hier mal ein debug auschnitt aus meinem prog:
So funktioniert der Code, der Signalhandler spricht an.
Sobald ich nun in der run() methode von diskjockey eine print ausgabe einbaue, geht der signalhandler nicht mehr. Es wird nur noch die ausgabe von print in der run-methode ausgegeben, nicht mehr die von der while-schleife im hauptprogramm.
any hints ??
mfg
Mauser
mittlerweile habe ich bei mir tiefere fehler entdeckt, es liegt also nicht (nur) an os.waitpid.
hier mal ein debug auschnitt aus meinem prog:
Code: Alles auswählen
class diskjockey(threading.Thread):
def __init__(self,mp3_player,jukebox):
threading.Thread.__init__(self)
self.mp3player=mp3_player
self.jukebox=jukebox
self.session_pid=0
self.stopped=0
#signal.signal(signal.SIGTERM,self.sighandler)
def run(self):
while self.stopped==0:
a=9
#print "test"
def main():
my_conf=config()
new_pid=0
pid=os.fork()
if pid == 0:
signal.signal(signal.SIGTERM,sighandler)
os.setsid()
stop=0
player1=mplayer('/usr/bin/mpg123')
pyrasdb=xmldb(my_conf)
pyrasdb.parse()
pyrasdb.file_to_mem()
juke=jukebox(my_conf,pyrasdb)
juke.start()
disco_stu=diskjockey(player1,juke)
disco_stu.start()
while 1:
print "o"
else:
sys.exit(0)
Sobald ich nun in der run() methode von diskjockey eine print ausgabe einbaue, geht der signalhandler nicht mehr. Es wird nur noch die ausgabe von print in der run-methode ausgegeben, nicht mehr die von der while-schleife im hauptprogramm.
any hints ??
mfg
Mauser
baue mal ein time.sleep(1.23) in die while-Schleifen ein.
Wie ist sighandler definiert?
cu beyond
Wie ist sighandler definiert?
cu beyond
hi,
ich habe jetzt das sleep in die while schleifen eingebaut. nun benötigt man einen signalhandler in diskjockey. ich habe einen in __init__ eingefügt.
der signalhandler sieht so aus:
Sende ich nun mit "killall pyras.py" ein TERM signal, beendet sich der diskjockey-thread korrekt, der hauptprozess, der diskjockey aufgerufen hat, bleit jedoch bestehen. der signalhandler des hauptthreads wird jedoch nicht aufgerufen.
wenn ich jetzt noch den signalhandler im hauptthread einbauen zum laufen bekomme, wäre das probleme zunächst gelöst..
mfg
Mauser
ich habe jetzt das sleep in die while schleifen eingebaut. nun benötigt man einen signalhandler in diskjockey. ich habe einen in __init__ eingefügt.
der signalhandler sieht so aus:
Code: Alles auswählen
def sighandler(arg1,arg2):
print "ich beende mich jetzt"
sys.exit(0)
wenn ich jetzt noch den signalhandler im hauptthread einbauen zum laufen bekomme, wäre das probleme zunächst gelöst..
mfg
Mauser
Ich bin mir nicht sicher, ob es mit 2 Handlern klappt. Falls nämlich die Handler in einer Table (so wie früher die Interrupts in DOS) gespeichert sind, kann's pro Programm nur einen Handler pro Signal geben. Die Treads in Python sind IMO normalerweise nicht "green". Also gibt's eigentlich schon mehrere Prozesse ....
Ich benutze für meine Handler eigentlich immer globale Variablen, die ich prüfe, und nur einen Handler pro Signal. Werden's viele Handler/Variablen kann man sie auch ein einem Modul verpacken.
cu beyond
Ich benutze für meine Handler eigentlich immer globale Variablen, die ich prüfe, und nur einen Handler pro Signal. Werden's viele Handler/Variablen kann man sie auch ein einem Modul verpacken.
cu beyond
hi,
erstmal danke für deine hilfe.ich habe es jetzt durch einen hack gelöst.. es ist richtig, das nur ein signalhandler gesetzt werden kann. mit dieser erkenntnis bereichert, habe ich einen im haupthread angesiedelt. jetzt blieb noch das problem mit os.waitpid: natuerlich hat es immer noch blockiert zuerst habe ich es durch eine schleife ersetzt, die in /proc/ schaut, ob der mpg123 prozess noch vorhanden ist. dies ging auch nicht, da der python prozess anscheinend das /proc file für den mpg123 prozess blockiert hat, so dass es net gelöscht wurde (obwohl ich sleep's eingebaut habe). ich habe nun einfach den mpg123 prozess aus dem signalhandler heraus gekillt. dank deinem tip mit globalen variablen war das kein problem. ich hatte gar nicht daran gedacht, weil ich sowas sonst immer als unnötig abtue..
mfg
Mauser
PS: Ach ja. es ging hier um einen mp3server, der sich per jabber steuern lässt und ein Web - sowie ein XML-RPC interface zur steuerung besitzt, die natürlich alle in einzelnen threads laufen
erstmal danke für deine hilfe.ich habe es jetzt durch einen hack gelöst.. es ist richtig, das nur ein signalhandler gesetzt werden kann. mit dieser erkenntnis bereichert, habe ich einen im haupthread angesiedelt. jetzt blieb noch das problem mit os.waitpid: natuerlich hat es immer noch blockiert zuerst habe ich es durch eine schleife ersetzt, die in /proc/ schaut, ob der mpg123 prozess noch vorhanden ist. dies ging auch nicht, da der python prozess anscheinend das /proc file für den mpg123 prozess blockiert hat, so dass es net gelöscht wurde (obwohl ich sleep's eingebaut habe). ich habe nun einfach den mpg123 prozess aus dem signalhandler heraus gekillt. dank deinem tip mit globalen variablen war das kein problem. ich hatte gar nicht daran gedacht, weil ich sowas sonst immer als unnötig abtue..
mfg
Mauser
PS: Ach ja. es ging hier um einen mp3server, der sich per jabber steuern lässt und ein Web - sowie ein XML-RPC interface zur steuerung besitzt, die natürlich alle in einzelnen threads laufen
Also dann gutes vorankommen. Steuerung über Jabber klingt ganz gut
Übrigens mit dem "blockierten /proc file". Es könnte sein, daß ein
braucht.
cu beyond
Übrigens mit dem "blockierten /proc file". Es könnte sein, daß ein
Code: Alles auswählen
f= open( ...
...
...
...
f.close()
del f
sleep(1.23)
cu beyond
hi,
ich habe den zugriff auf proc per os.path.isdir() gemacht. will mich da auch nicht weiter vertiefen, da es IMHO besser ist einmal bei sigterm mpg123 zu killen als ständig das dateisystem abzufragem..
Die Jabber Unterstützung funktioniert übrigens schon, sowie alle wesentlichen features des servers. habe nur dummerweise vor lauter "featuregeilheit" nicht daran gedacht , die signalhandler einzubauen..
mfg
Mauser
PS: suche immer noch interessierte, die sich an dem projekt beteiligen
ich habe den zugriff auf proc per os.path.isdir() gemacht. will mich da auch nicht weiter vertiefen, da es IMHO besser ist einmal bei sigterm mpg123 zu killen als ständig das dateisystem abzufragem..
Die Jabber Unterstützung funktioniert übrigens schon, sowie alle wesentlichen features des servers. habe nur dummerweise vor lauter "featuregeilheit" nicht daran gedacht , die signalhandler einzubauen..
mfg
Mauser
PS: suche immer noch interessierte, die sich an dem projekt beteiligen
Bin leider zu sehr beschäftigt. Nächstes Semester wechsle ich an eine andere Uni. Und ich bau mir gerade noch Aktivboxen damit ich dort auch Musik hören kann ...
cu beyond
cu beyond