Autor Thema: [PATCH] Blocking.pm - Verwenden von threads->exit()  (Gelesen 2525 mal)

Offline Markus Bloch

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 3551
[PATCH] Blocking.pm - Verwenden von threads->exit()
« am: 05 Februar 2013, 00:17:36 »
Hallo zusammen,

da bei einem fork() unter Window nur ein Thread angelegt wird, würde ich empfehlen hier generell (sowohl unter UNIX, als auch unter Windows) den Child-Process/Fork mittels threads->exit() zu beenden.

Vorteil:

Es gibt keine Fehlermeldungen unter Windows wie:


Select error -1 (10038)
Error in PurgeComm at fhem.pl line 0.
Das Handle ist ung³ltig.
Error in GetCommTimeouts at fhem.pl line 0.
Error Closing handle 132 for \\.\com3
Das Handle ist ung³ltig.
Error closing Read Event handle 176 for \\.\com3
Das Handle ist ung³ltig.
Error closing Write Event handle 180 for \\.\com3
Das Handle ist ung³ltig.


Diese Fehlermeldungen entstehen, da bei einem normalen exit(); sämtliche offenen File-Sockets geflushed und geschlossen werden. Da aber bei einem Thread dieser immer noch mit dem Mutter-Prozess verbunden sind, läuft man dadurch in die genannten Fehler.

Die Benutzung von threads->exit() verhindert das, da hier nur der Thread beendet wird, die File Sockets aber nicht geschlossen werden. Dadurch kommt es zu keinen Beeinträchtigungen des Mutter-Prozesses und deren Sockets und der Thread beendet sich normal.

Dies funktioniert auch unter UNIX-Systemen bei einem Unix-Fork() da ja der Mutterprozess ebenfalls ein Thread ist (nämlich der Haupt-Thread) und dadurch als kompletter Prozess beendet wird.

Ich würde eh gerne die Blocking.pm auf thread-basiert umstellen. Dadurch entfällt der Rückkanal über einen Telnet Port, da das Ergebniss intern über eine Thread-Queue zurückgegeben würde.

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 20196
Aw: [PATCH] Blocking.pm - Verwenden von threads->exit()
« Antwort #1 am: 05 Februar 2013, 09:29:00 »
Die perl Versionen auf den Fritzboxen sind nicht thread-faehig. Weiterhin will ich bei unserem sehr heterogenen Programmiererschaar nicht mit thread-Programmierung anfangen.

Ich hab jetzt Blocking.pm so modifiziert, dass es unter Windows threads->exit aufruft, sonst exit. Testen konnte ich es nur unter Unix.

Offline Markus Bloch

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 3551
Aw: [PATCH] Blocking.pm - Verwenden von threads->exit()
« Antwort #2 am: 05 Februar 2013, 09:42:10 »
Alles klar, werde ich heute Abend mal testen.

Vielen Dank

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Offline Markus Bloch

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 3551
Aw: [PATCH] Blocking.pm - Verwenden von threads->exit()
« Antwort #3 am: 05 Februar 2013, 18:42:55 »
Hallo Rudi,

schonmal Danke fürs einchecken. Unter Windows klappt das aber so noch nicht, da das Modul threads zum Zeitpunkt des Kills nicht geladen ist.


sub
BlockingExit($)
{
  my $client = shift;

  if($^O =~ m/Win/) {
    close($client) if($client);
   
    use threads;
    threads->exit();

  } else {
    exit(0);

  }
}



Am besten direkt vor das Exit ein use threads; setzen. So klappt es bei mir auch unter Windows und threads wird nur unter Windows geladen.

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Offline Markus Bloch

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 3551
Aw: [PATCH] Blocking.pm - Verwenden von threads->exit()
« Antwort #4 am: 05 Februar 2013, 18:47:38 »
unter Windows gibt es im Log ebenfalls bei jedem Aufruf von BlockingCall() ein Eintrag im Log wie:

Zitat

2013.02.05 18:40:15 1: Terminated -1992
2013.02.05 18:40:36 1: Terminated -192
2013.02.05 18:40:58 1: Terminated -1716
2013.02.05 18:41:19 1: Terminated -3756
2013.02.05 18:41:40 1: Terminated -2576
2013.02.05 18:42:01 1: Terminated -1552
2013.02.05 18:42:22 1: Terminated -836
2013.02.05 18:42:43 1: Terminated -2552
2013.02.05 18:43:04 1: Terminated -928


Das liegt daran, das unter Windows in Perl die Parent Process Id's als negative Zahlen dargestellt werden. Hier würde ich folgende Änderung vorschlagen.


sub
BlockingKill($)
{
  my $pid = shift;
  if($^O =~ m/Win/) {
  Log 1, "Terminated $pid" if($pid < 0 && kill(9, $pid));
  }
  else
  {
  Log 1, "Terminated $pid" if($pid && kill(9, $pid));
  }
}


Ich hoffe das ist für dich in Ordnung.

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Offline Markus Bloch

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 3551
Aw: [PATCH] Blocking.pm - Verwenden von threads->exit()
« Antwort #5 am: 05 Februar 2013, 19:18:51 »
hmm klappt aber nich so wie gedacht, da die kill-Funktion unter windows immer erfolgreich zurückgibt.

Ansonsten evtl. ganz weglassen unter Windows?

Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Offline rudolfkoenig

  • Administrator
  • Hero Member
  • *****
  • Beiträge: 20196
Aw: [PATCH] Blocking.pm - Verwenden von threads->exit()
« Antwort #6 am: 06 Februar 2013, 20:14:00 »
Hab jetzt
  eval "require threads;";

und
if($^O !~ m/Win/) {
   Log 1, "Terminated $pid" if($pid && kill(9, $pid));
 }


hinzugefuegt. "use" wird immer am Anfang ausgefuehrt, unabhaengig vom "if", und mit dem Windows threading Modell ist ein kill problematisch, steht jedenfalls in "perldoc perlfork" so drin.

 

decade-submarginal