Prozesse / Threads und signal

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.
Antworten
mauser
User
Beiträge: 12
Registriert: Donnerstag 19. August 2004, 19:28

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
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

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
mauser
User
Beiträge: 12
Registriert: Donnerstag 19. August 2004, 19:28

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
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

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
mauser
User
Beiträge: 12
Registriert: Donnerstag 19. August 2004, 19:28

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:

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)
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
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

baue mal ein time.sleep(1.23) in die while-Schleifen ein.

Wie ist sighandler definiert?

cu beyond
mauser
User
Beiträge: 12
Registriert: Donnerstag 19. August 2004, 19:28

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:

Code: Alles auswählen

def sighandler(arg1,arg2): 
 print "ich beende mich jetzt"
 sys.exit(0)
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
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

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
mauser
User
Beiträge: 12
Registriert: Donnerstag 19. August 2004, 19:28

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
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

Also dann gutes vorankommen. Steuerung über Jabber klingt ganz gut :-)

Ü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)
braucht.

cu beyond
mauser
User
Beiträge: 12
Registriert: Donnerstag 19. August 2004, 19:28

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 :lol:
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

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
Antworten