alarm() unter Windows

alarm() unter Windows

am 11.01.2007 08:49:39 von Ferry Bolhar

Hallo,

ich hatte das schon unter dem Thread "Prozess Check unter W2003" gepostet,
aber keine Antwort bekommen - vielleicht ist es übersehen worden, daher
jetzt
nochmals als eigener Thread:

Ich habe folgenden Code:

eval {
$SIG{ALRM} = sub {die "\nTimeout!\n"};
alarm 3;
print 'Eingabe: ';
my $input = ;
alarm 0;
};
die "$@\n" if $@;

Unter Linux funktioniert das wie erwartet - wird nicht innerhalb von drei
Sekunden etwas eingeben, wird mit "Timeout!" abgebrochen. Unter
W2003 allerdings wird "ewig" auf eine Eingabe gewartet, der alarm-
Handler wird nie ausgeführt.

Weiß jemand, was man ändern muss, damit man Timeouts auch unter
Windows implementieren kann? Es geht dabei natürlich nicht um inter-
aktive Eingaben, sondern um Lesen über TCP/IP Verbindungen (Sockets),
bei denen es in der Natur der Sache liegt, dass sich manchmal eine
Verbindung aufhängt oder ein Request unbeantwortet bleibt. Das muss
ich in meinem Code entsprechend abfangen.

Wer kann mir sagen, wie ich das unter W2003 hinbekomme?

Danke & LG,

Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: alarm() unter Windows

am 11.01.2007 15:06:32 von Ingo Menger

Ferry Bolhar schrieb:

> Hallo,
>
> ich hatte das schon unter dem Thread "Prozess Check unter W2003" gepostet,
> aber keine Antwort bekommen - vielleicht ist es übersehen worden, daher
> jetzt
> nochmals als eigener Thread:
>
> Ich habe folgenden Code:
>
> eval {
> $SIG{ALRM} =3D sub {die "\nTimeout!\n"};
> alarm 3;
> print 'Eingabe: ';
> my $input =3D ;
> alarm 0;
> };
> die "$@\n" if $@;
>
> Unter Linux funktioniert das wie erwartet - wird nicht innerhalb von drei
> Sekunden etwas eingeben, wird mit "Timeout!" abgebrochen. Unter
> W2003 allerdings wird "ewig" auf eine Eingabe gewartet, der alarm-
> Handler wird nie ausgeführt.
>
> Weiß jemand, was man ändern muss, damit man Timeouts auch unter
> Windows implementieren kann? Es geht dabei natürlich nicht um inter-
> aktive Eingaben, sondern um Lesen über TCP/IP Verbindungen (Sockets),
> bei denen es in der Natur der Sache liegt, dass sich manchmal eine
> Verbindung aufhängt oder ein Request unbeantwortet bleibt. Das muss
> ich in meinem Code entsprechend abfangen.

perldoc -f select

Re: alarm() unter Windows

am 11.01.2007 16:39:25 von Ferry Bolhar

Ingo Menger:

> perldoc -f select

Verstehe ich nicht ganz.

Vielleicht habe ich mich unklar ausgedrückt. Ich mache ein

@resp = qx[sc <\\remotehost> interrogate ""];

und möchte sicherstellen, dass der sc-Befehl nicht endlos wartet
(was er tut, wenn sich das betreffende Service "aufgehängt" hat).

Wie kann ich da select verwenden, um ein Timeout zu
implementieren?

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: alarm() unter Windows

am 11.01.2007 16:56:13 von Ingo Menger

Ferry Bolhar schrieb:

> Ingo Menger:
>
> > perldoc -f select
>
> Verstehe ich nicht ganz.
>
> Vielleicht habe ich mich unklar ausgedrückt.

Nö, Du hattest gesagt, daß Du auf sockets und filehandles warten
willst.

> Ich mache ein
>
> @resp =3D qx[sc <\\remotehost> interrogate ""];
>
> und möchte sicherstellen, dass der sc-Befehl nicht endlos wartet
> (was er tut, wenn sich das betreffende Service "aufgehängt" hat).

Ok, dann kannst Du eben qx nicht nehmen. Aber dafür

open SC "sc \\\\remotehost interrogate service |"

und dann select auf SC.

Re: alarm() unter Windows

am 12.01.2007 15:41:29 von Ferry Bolhar

Ingo Menger:

>>> perldoc -f select
>>
>> Verstehe ich nicht ganz.
>>
>> Vielleicht habe ich mich unklar ausgedrückt.
>>
> Nö, Du hattest gesagt, daß Du auf sockets und filehandles warten
> willst.

Hatte ich so nicht gemeint, sorry. Also doch unklar ausgedrückt. :-)

> Ok, dann kannst Du eben qx nicht nehmen. Aber dafür
>
> open SC "sc \\\\remotehost interrogate service |"

Geht auch nicht - bleibt genauso hängen. Mein Code (zum Testen):

open SC, q[sleep 10 |] or die "Failed to open: $!\n";
vec(my $rin,fileno(SC),1 = 1;
my ($nfound,$timeleft) = select($rin,undef,undef,3);
my $inp = ;
print "nfound: $nfound, timeleft: $timeleft\n";

Nach einer Wartezeit von 10 Sekunden bekomme ich:

nfound: -1, timeleft: 3

Ändere ich den Sekundenwert in select(), so ändernt sich
auch der ausgegebene timeleft-Wert.

Was mache ich falsch? Könntest du ein unter W2x
funktionierendes Codebeispiel posten?

Danke & schöne Grüße aus Wien,

Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: alarm() unter Windows

am 12.01.2007 16:24:42 von Ingo Menger

Ferry Bolhar schrieb:

> Ingo Menger:

> Geht auch nicht - bleibt genauso hängen. Mein Code (zum Testen):
>
> open SC, q[sleep 10 |] or die "Failed to open: $!\n";
> vec(my $rin,fileno(SC),1 =3D 1;
> my ($nfound,$timeleft) =3D select($rin,undef,undef,3);
> my $inp =3D ;
> print "nfound: $nfound, timeleft: $timeleft\n";
>
> Nach einer Wartezeit von 10 Sekunden bekomme ich:
>
> nfound: -1, timeleft: 3
>
> Ändere ich den Sekundenwert in select(), so ändernt sich
> auch der ausgegebene timeleft-Wert.
>
> Was mache ich falsch?

Du liest von SC, ohne das select() Ergebnis ausgewertet zu haben.
Ich weiß jetzt nicht aus dem Kopf, wie das genau geht, aber perldoc -f
select müßte an sich ein funktionierendes Codebeispiel enthalten.
Grundsätzlich ist es so, daß Du nur von Filehandles lesen darfst, von
denen Dir select gesagt hat, daß sie lesebereit sind, sonst hängst
Du. Und vielleicht ist es ganz gut, read oder sogar sysread zu
benutzen.
An und für sich sollte select unter Windows genausogut funktionieren
wie unter UNIX.

Habe gerade nochmal geschaut:

"Most systems do not bother to return anything useful in $timeleft ...
Note: not all implementations are capable of returning the $timeleft.
If not, they always return $timeleft equal to the supplied $timeout."

Aha, eine Erklärung für die 3.

"WARNING: One should not attempt to mix buffered I/O (like "read" or
) with "select", except as permitted by POSIX, and even then only
on POSIX systems. You have to use "sysread" instead."

Also: Dein Script hat 3 Sekunden in select geschlafen ohne daß das
Filehandle ready geworden wäre, danach hast Du auf Eingabe gewartet
(weitere 7 Sekunden).
Völlig korrekt.
Aber Du willst:

if (1 == select(.....)) {
# sysread from SC
}
else {
# timeout
}

Re: alarm() unter Windows

am 12.01.2007 19:36:59 von Ingo Menger

Ingo Menger schrieb:

Noch ein Nachtrag bezüglich:


> "WARNING: One should not attempt to mix buffered I/O (like "read" or
> ) with "select", except as permitted by POSIX, and even then only
> on POSIX systems. You have to use "sysread" instead."

Wenn dieses sc-Kommando ein "alles oder nichts"-Prozeß ist, d.h., wenn
Du weißt, daß es nicht mehr hängenbleiben wird, nachdem es erst
einmal angefangen hat, irgendwas auszugeben, brauchst Du sysread() wohl
nicht. Dann geht das ganz normale .

Was nicht vernünftig gehen kann ist select nachdem Du mindestens
einmal in den Puffer gelesen hast.

Re: alarm() unter Windows

am 13.01.2007 22:18:40 von Peter Arnhold

Ingo Menger schrieb:
> Ferry Bolhar schrieb:
>
>> Ingo Menger:
[...]

> An und für sich sollte select unter Windows genausogut funktionieren
> wie unter UNIX.

Wenn es sich in letzter Zeit nicht geändert hat(?): nein. Nur auf Sockets.

Gruß,
Peter

Re: alarm() unter Windows

am 13.01.2007 22:29:19 von Peter Arnhold

Ferry Bolhar schrieb:
> Ingo Menger:
>
>>>> perldoc -f select
>>> Verstehe ich nicht ganz.
>>>
>>> Vielleicht habe ich mich unklar ausgedrückt.
>>>
>> Nö, Du hattest gesagt, daß Du auf sockets und filehandles warten
>> willst.
>
> Hatte ich so nicht gemeint, sorry. Also doch unklar ausgedrückt. :-)
>
>> Ok, dann kannst Du eben qx nicht nehmen. Aber dafür
>>
>> open SC "sc \\\\remotehost interrogate service |"
>
> Geht auch nicht - bleibt genauso hängen. Mein Code (zum Testen):
>
> open SC, q[sleep 10 |] or die "Failed to open: $!\n";
> vec(my $rin,fileno(SC),1 = 1;
> my ($nfound,$timeleft) = select($rin,undef,undef,3);
> my $inp = ;
> print "nfound: $nfound, timeleft: $timeleft\n";
>
> Nach einer Wartezeit von 10 Sekunden bekomme ich:
>
> nfound: -1, timeleft: 3
>
> Ändere ich den Sekundenwert in select(), so ändernt sich
> auch der ausgegebene timeleft-Wert.
>
> Was mache ich falsch? Könntest du ein unter W2x
> funktionierendes Codebeispiel posten?
>
> Danke & schöne Grüße aus Wien,
>
> Ferry
>

Hallo Ferry,

dein Beispiel-Code - ist das wirklich das, was Du getestet hast? Ich denke nicht.

Mir wäre neu, dass man unter Win32 select oder IO::Select für andere Handles
außer Sockets verwenden kann. Unter Win32 kommt select auf FH's immer *sofort*
zurück. Die Verzögerung in Deinem Fall hinge einzig am sleep, dass select ist
wertlos.

Ich würde hier nochmal den Tip von Bianka wiederholen: das richtige Werkzeug
für umfassende Informationen über Win32-Rechner ist WMI. Oder im einfachsten
Fall für Dienste Win32::Service.

Gruß,
Peter

Re: alarm() unter Windows

am 15.01.2007 11:24:07 von Ferry Bolhar

Peter Arnhold:

> dein Beispiel-Code - ist das wirklich das, was Du getestet hast? Ich denke
nicht.

Doch, freilich. Warum glaubst du etwas anderes?

> Mir wäre neu, dass man unter Win32 select oder IO::Select für andere
Handles
> außer Sockets verwenden kann. Unter Win32 kommt select auf FH's immer
*sofort*
> zurück.

Wo ist das dokumentiert? Welche Alternative(n) gibt es?

> Ich würde hier nochmal den Tip von Bianka wiederholen: das richtige
Werkzeug
> für umfassende Informationen über Win32-Rechner ist WMI. Oder im
einfachsten
> Fall für Dienste Win32::Service.

Das löst aber das Problem des "hängenden" Services nicht. Es ist nur eine
andere Schnittstelle.

Oder wir gehen das Problem anderesrum an - gibt es eine Möglichkeit, ein
Windows-Service auch von einem Linux-Rechner anzusprechen?

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: alarm() unter Windows

am 15.01.2007 11:36:31 von Ferry Bolhar

Ingo Menger:

> Du liest von SC, ohne das select() Ergebnis ausgewertet zu haben.
> Ich weiß jetzt nicht aus dem Kopf, wie das genau geht, aber perldoc -f
> select müßte an sich ein funktionierendes Codebeispiel enthalten.

Für meine Situation leider nicht.

> Grundsätzlich ist es so, daß Du nur von Filehandles lesen darfst, von
> denen Dir select gesagt hat, daß sie lesebereit sind, sonst hängst
> Du. Und vielleicht ist es ganz gut, read oder sogar sysread zu
> benutzen.
> An und für sich sollte select unter Windows genausogut funktionieren
> wie unter UNIX.

[...]

> Aber Du willst:
>
> if (1 == select(.....)) {
> # sysread from SC
> }
> else {
> # timeout
> }

Gut, ich habe das Skript jetzt wie folgt geändert:

open SC,q[sc query messenger|] or die;
vec(my $rin,fileno(SC),1) = 1;
my $nfound = select($rin,undef,undef,3);
if ($nfound > 1) {
sysread SC,$inbuf,500;
}else {
die "Timeout!\n";
}
print "$inbuf\n";

Leider liefert select immer -1 zurück - auch wenn von SC tatsächlich
etwas gelesen werden kann!

Was mache ich jetzt noch falsch?

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: alarm() unter Windows

am 15.01.2007 12:14:25 von Peter Arnhold

Ferry Bolhar schrieb:
> Ingo Menger:
>
>> Du liest von SC, ohne das select() Ergebnis ausgewertet zu haben.
>> Ich weiß jetzt nicht aus dem Kopf, wie das genau geht, aber perldoc -f
>> select müßte an sich ein funktionierendes Codebeispiel enthalten.
>
> Für meine Situation leider nicht.
>
>> Grundsätzlich ist es so, daß Du nur von Filehandles lesen darfst, von
>> denen Dir select gesagt hat, daß sie lesebereit sind, sonst hängst
>> Du. Und vielleicht ist es ganz gut, read oder sogar sysread zu
>> benutzen.
>> An und für sich sollte select unter Windows genausogut funktionieren
>> wie unter UNIX.
>
> [...]
>
>> Aber Du willst:
>>
>> if (1 == select(.....)) {
>> # sysread from SC
>> }
>> else {
>> # timeout
>> }
>
> Gut, ich habe das Skript jetzt wie folgt geändert:
>
> open SC,q[sc query messenger|] or die;
> vec(my $rin,fileno(SC),1) = 1;
> my $nfound = select($rin,undef,undef,3);
> if ($nfound > 1) {
> sysread SC,$inbuf,500;
> }else {
> die "Timeout!\n";
> }
> print "$inbuf\n";
>
> Leider liefert select immer -1 zurück - auch wenn von SC tatsächlich
> etwas gelesen werden kann!
>
> Was mache ich jetzt noch falsch?
>
> LG, Ferry
>

perldoc perlport

select RBITS,WBITS,EBITS,TIMEOUT
Only implemented on sockets. (Win32, VMS)

Re: alarm() unter Windows

am 15.01.2007 13:34:11 von Ingo Menger

Peter Arnhold schrieb:

> Ingo Menger schrieb:
> > Ferry Bolhar schrieb:
> >
> >> Ingo Menger:
> [...]
>
> > An und für sich sollte select unter Windows genausogut funktionieren
> > wie unter UNIX.
>
> Wenn es sich in letzter Zeit nicht geändert hat(?): nein. Nur auf Socke=
ts.

Upps. Ist das so.
Dann nehme ich alles zurück :)

Re: alarm() unter Windows

am 15.01.2007 17:17:47 von Ferry Bolhar

Peter Arnhold:

> perldoc perlport
>
> select RBITS,WBITS,EBITS,TIMEOUT
> Only implemented on sockets. (Win32, VMS)

Oh. Danke. Jetzt ist alles klar.

Sehe ich das richtig, dass es für mein Problem keine Lösung gibt?

Scheint bei mir schön langsam schon chronisch zu sein... :-(

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: alarm() unter Windows

am 15.01.2007 18:02:32 von Frank Seitz

Ferry Bolhar wrote:
> Peter Arnhold:
>>
>>perldoc perlport
>>
>>select RBITS,WBITS,EBITS,TIMEOUT
>> Only implemented on sockets. (Win32, VMS)
>
> Oh. Danke. Jetzt ist alles klar.
>
> Sehe ich das richtig, dass es für mein Problem keine Lösung gibt?

Habe mir gerade Dein Eingangsposting durchgelesen: select()
ist die Lösung, indem Du es auf den Socket anwendest. Select()
kehrt zurück, wenn I/O möglich ist oder die vorgegebene
Zeit verstrichen ist. Die Programmierung ist nur etwas anders.

Ich persönlich würde im Normalfall allerdings kein
Timeout auf einem TCP-Socket programmieren, da das Protokoll
gegen das Abreißen der Verbindung ohnehin absichert.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: alarm() unter Windows

am 15.01.2007 18:40:56 von Peter Arnhold

Frank Seitz schrieb:
> Ferry Bolhar wrote:
>> Peter Arnhold:
>>> perldoc perlport
>>>
>>> select RBITS,WBITS,EBITS,TIMEOUT
>>> Only implemented on sockets. (Win32, VMS)
>> Oh. Danke. Jetzt ist alles klar.
>>
>> Sehe ich das richtig, dass es für mein Problem keine Lösung gibt?
>
> Habe mir gerade Dein Eingangsposting durchgelesen: select()
> ist die Lösung, indem Du es auf den Socket anwendest. Select()
> kehrt zurück, wenn I/O möglich ist oder die vorgegebene
> Zeit verstrichen ist. Die Programmierung ist nur etwas anders.
>
> Ich persönlich würde im Normalfall allerdings kein
> Timeout auf einem TCP-Socket programmieren, da das Protokoll
> gegen das Abreißen der Verbindung ohnehin absichert.
>
> Grüße
> Frank

Aber nur, wenn das Script nichts weiter macht und Zeit keine Rolle spielt.
Schon ein einfaches ziehen des Patchkabels am nächsten Switch lässt den Socket
verhungern, ohne Dir bescheid zu geben.

Gruß,
Peter

Re: alarm() unter Windows

am 15.01.2007 19:51:09 von Frank Seitz

Peter Arnhold wrote:
> Frank Seitz schrieb:
>>
>>Ich persönlich würde im Normalfall allerdings kein
>>Timeout auf einem TCP-Socket programmieren, da das Protokoll
>>gegen das Abreißen der Verbindung ohnehin absichert.
>
> Aber nur, wenn das Script nichts weiter macht und Zeit keine Rolle spielt.
> Schon ein einfaches ziehen des Patchkabels am nächsten Switch lässt den Socket
> verhungern, ohne Dir bescheid zu geben.

Sicher, aber macht es Sinn, gegen so eine Fehlersituation mit
einem Timeout anzuprogrammieren? In der Situation geht sowieso nichts
mehr, bis das Kabel wieder eigesteckt wird. Ohne Timeout geht es
danach weiter. Bei einem Timeout besteht die Gefahr,
dass eine zwar langsame, aber aktive Verbindung ggf. willkürlich
unterbrochen wird.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: alarm() unter Windows

am 16.01.2007 13:24:57 von Ferry Bolhar

Frank Seitz:

> Sicher, aber macht es Sinn, gegen so eine Fehlersituation mit
> einem Timeout anzuprogrammieren? In der Situation geht sowieso nichts
> mehr, bis das Kabel wieder eigesteckt wird. Ohne Timeout geht es
> danach weiter. Bei einem Timeout besteht die Gefahr,
> dass eine zwar langsame, aber aktive Verbindung ggf. willkürlich
> unterbrochen wird.

In meinem Fall geht es darum. dass ein Aufruf eines Programms mit
qx hängt, weil das Service, das damit abgefragt wird, ebenfalls hängt.
Dh., der Request wird nicht zurückgewiesen (das würde das Programm
ja merken), sondern er wird akzeptiert, aber nicht beantwortet:

sc \\ctisrva interrogate "Applix FlowChartServer"

liefert eine Antwort mit "PID:" zurück, falls das Service läuft oder
"has not been started", wenn es gestoppt ist. Das kann ich leicht
extrahieren und so feststellen, ob es gestartet werden muss. Hat sich
das Service aber "aufgehängt" (weil der dahinterliegende Prozess
hängt), bleibt die Anfrage mit "sc" einfach hängen. Das muss ich
irgendwie erkennen (durch einen Timeout), weil dann das Service
gestoppt und wieder gestartet werden muss.

Ach ja: das soll natürlich automatisch (als Task-Planer-Job)
ablaufen. Und daher benötige ich das Timeout, weil sonst ein
gestarteter Task hängt und nicht mehr fertig wird, d.h., das System
wird sonst nach und nach mit gestarteten Tasks überschwemmt,
die aber nie mehr beendet werden. Außerdem bleibt das Service
dann in diesem unsauberen Status.

Ich hoffe, es ist jetzt klar, wozu ich die Timeout-Lösung brauche.
Dass das weder mit alarm() noch mit select() funktioniert, ist etwas
frustierend. Weiß jemand vielleicht sonst noch einen Weg?

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: alarm() unter Windows

am 16.01.2007 13:43:19 von Peter Arnhold

Ferry Bolhar schrieb:
> Frank Seitz:
>
>> Sicher, aber macht es Sinn, gegen so eine Fehlersituation mit
>> einem Timeout anzuprogrammieren? In der Situation geht sowieso nichts
>> mehr, bis das Kabel wieder eigesteckt wird. Ohne Timeout geht es
>> danach weiter. Bei einem Timeout besteht die Gefahr,
>> dass eine zwar langsame, aber aktive Verbindung ggf. willkürlich
>> unterbrochen wird.
>
> In meinem Fall geht es darum. dass ein Aufruf eines Programms mit
> qx hängt, weil das Service, das damit abgefragt wird, ebenfalls hängt.
> Dh., der Request wird nicht zurückgewiesen (das würde das Programm
> ja merken), sondern er wird akzeptiert, aber nicht beantwortet:
>
> sc \\ctisrva interrogate "Applix FlowChartServer"
>
> liefert eine Antwort mit "PID:" zurück, falls das Service läuft oder
> "has not been started", wenn es gestoppt ist. Das kann ich leicht
> extrahieren und so feststellen, ob es gestartet werden muss. Hat sich
> das Service aber "aufgehängt" (weil der dahinterliegende Prozess
> hängt), bleibt die Anfrage mit "sc" einfach hängen. Das muss ich
> irgendwie erkennen (durch einen Timeout), weil dann das Service
> gestoppt und wieder gestartet werden muss.

Merkwürdig, ich bekomme sc bei mir nicht dazu, "ewig" zu warten. Selbst wenn
ich einen Dienst "hängen" lasse.

> Ach ja: das soll natürlich automatisch (als Task-Planer-Job)
> ablaufen. Und daher benötige ich das Timeout, weil sonst ein
> gestarteter Task hängt und nicht mehr fertig wird, d.h., das System
> wird sonst nach und nach mit gestarteten Tasks überschwemmt,
> die aber nie mehr beendet werden. Außerdem bleibt das Service
> dann in diesem unsauberen Status.
>
> Ich hoffe, es ist jetzt klar, wozu ich die Timeout-Lösung brauche.
> Dass das weder mit alarm() noch mit select() funktioniert, ist etwas
> frustierend. Weiß jemand vielleicht sonst noch einen Weg?

Hast Du keine andere Möglichkeit, die Dienste zu prüfen? Was Du vom
Dienstemanager über einen Dienst erfährst, muss in keiner Weise etwas mit der
Funktionsfähigkeit des eigentlichen Programms zu tun haben. Sieh Dir vielleicht
mal informativ Win32::Daemon an.
Es ist wie mit der Wasseruhr. Wenn sich die dreht, muss dass Wasser nicht mehr
unbedingt in die Wanne laufen, es kann schon beim Nachbarn aus der Lampe
tropfen. Vielleicht hast Du die Möglichkeit, das korrekte Arbeiten an Hand von
Funktionalität zu prüfen, die der jeweilige Dienst erbringen soll?

Ansonsten vielleicht so in der Art, bis jemand was besseres weiß:

use Socket;
my($CHILD,$PARENT);
socketpair($CHILD,$PARENT,AF_UNIX,SOCK_STREAM,PF_UNSPEC) or die "$!\n";

if (fork) {
close $CHILD;

$SIG{CHLD} = 'IGNORE';
my $info = '';

vec(my $rin='',fileno($PARENT),1) = 1;
my $nfound = select($rin,undef,undef,2);
if ( $nfound ) {
sysread $PARENT,$info,0xffff;
}
else {
die "Timeout!\n";
}
print "info($nfound):$info\n";
}
else {
close $PARENT;
# open SC, q(perl -e "print qq(hello world\n);sleep 4" |) or
open SC, q(sc query messenger|) or
die "Failed to open: $!\n";
print $CHILD ;
exit;
}


Gruß,
Peter

Re: alarm() unter Windows

am 16.01.2007 14:15:42 von Frank Seitz

Ferry Bolhar wrote:
>
> In meinem Fall geht es darum. dass ein Aufruf eines Programms mit
> qx hängt, weil das Service, das damit abgefragt wird, ebenfalls hängt.
> Dh., der Request wird nicht zurückgewiesen (das würde das Programm
> ja merken), sondern er wird akzeptiert, aber nicht beantwortet:
>
> sc \\ctisrva interrogate "Applix FlowChartServer"
>
> liefert eine Antwort mit "PID:" zurück, falls das Service läuft oder
> "has not been started", wenn es gestoppt ist. Das kann ich leicht
> extrahieren und so feststellen, ob es gestartet werden muss. Hat sich
> das Service aber "aufgehängt" (weil der dahinterliegende Prozess
> hängt), bleibt die Anfrage mit "sc" einfach hängen. Das muss ich
> irgendwie erkennen (durch einen Timeout), weil dann das Service
> gestoppt und wieder gestartet werden muss.
>
> Ach ja: das soll natürlich automatisch (als Task-Planer-Job)
> ablaufen. Und daher benötige ich das Timeout, weil sonst ein
> gestarteter Task hängt und nicht mehr fertig wird, d.h., das System
> wird sonst nach und nach mit gestarteten Tasks überschwemmt,
> die aber nie mehr beendet werden. Außerdem bleibt das Service
> dann in diesem unsauberen Status.

Ich hatte nur Dein Eingangsposting gelesen, da stand etwas anderes.
Was Du machen möchtest - Prozess abbrechen, wenn dieser innerhalb
einer vorgegebenen Zeitspanne nicht terminiert -, geht bestimmt
auch unter Windows. Dem Prinzip nach musst Du hierzu einen
Childprozess starten, den vom Parent aus überwachen und
bei Zeitüberschreitung killen. Ggf. musst Du Dich mit
Systemprogrammierung unter Windows beschäftigen,
wenn es auf keinem der Unix-Wege geht. Da kann ich
Dir nicht weiterhelfen.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: alarm() unter Windows

am 16.01.2007 15:41:06 von hjp-usenet2

On 2007-01-15 18:51, Frank Seitz wrote:
> Peter Arnhold wrote:
>> Frank Seitz schrieb:
>>>Ich persönlich würde im Normalfall allerdings kein
>>>Timeout auf einem TCP-Socket programmieren, da das Protokoll
>>>gegen das Abreißen der Verbindung ohnehin absichert.
>>
>> Aber nur, wenn das Script nichts weiter macht und Zeit keine Rolle spielt.
>> Schon ein einfaches ziehen des Patchkabels am nächsten Switch lässt den Socket
>> verhungern, ohne Dir bescheid zu geben.
>
> Sicher, aber macht es Sinn, gegen so eine Fehlersituation mit
> einem Timeout anzuprogrammieren?

Häufig ja.

> In der Situation geht sowieso nichts mehr, bis das Kabel wieder
> eigesteckt wird. Ohne Timeout geht es danach weiter. Bei einem Timeout
> besteht die Gefahr, dass eine zwar langsame, aber aktive Verbindung
> ggf. willkürlich unterbrochen wird.

Sicher, die Gefahr besteht. Aber ohne Timeout besteht die Gefahr, dass
sich am Server immer mehr Serverprozesse ansammeln, die ewig darauf
warten, dass der Client wieder mal was schickt, was aber nie passieren
wird, weil der inzwischen abgeschalten wurde, oder die IP-Adresse
gewechselt hat oder sonstwie keine Möglichkeit mehr hat, die Verbindung
zu schließen.

Gerade in der Netzwerkprogrammierung sind Timeouts fast unerlässlich.
Häufig kann man sie allerdings an den TCP-Layer delegieren (z.B.
SO_KEEPALIVE).

hp


--
_ | Peter J. Holzer | > Wieso sollte man etwas erfinden was nicht
|_|_) | Sysadmin WSR | > ist?
| | | hjp@hjp.at | Was sonst wäre der Sinn des Erfindens?
__/ | http://www.hjp.at/ | -- P. Einstein u. V. Gringmuth in desd

Re: alarm() unter Windows

am 16.01.2007 20:22:07 von Frank Seitz

Peter J. Holzer wrote:
> On 2007-01-15 18:51, Frank Seitz wrote:
>>
>>Sicher, aber macht es Sinn, gegen so eine Fehlersituation mit
>>einem Timeout anzuprogrammieren?
>
> Häufig ja.

Ich bin skeptisch. Ich habe das noch nie gebraucht.

>>In der Situation geht sowieso nichts mehr, bis das Kabel wieder
>>eigesteckt wird. Ohne Timeout geht es danach weiter. Bei einem Timeout
>>besteht die Gefahr, dass eine zwar langsame, aber aktive Verbindung
>>ggf. willkürlich unterbrochen wird.
>
> Sicher, die Gefahr besteht. Aber ohne Timeout besteht die Gefahr, dass
> sich am Server immer mehr Serverprozesse ansammeln, die ewig darauf
> warten, dass der Client wieder mal was schickt, was aber nie passieren
> wird, weil der inzwischen abgeschalten wurde,

Wenn der Prozess beendet oder die Maschine ordentlich
heruntergefahren wurde, wird das der Gegenseite signalisiert.

> oder die IP-Adresse gewechselt hat oder sonstwie keine
> Möglichkeit mehr hat, die Verbindung zu schließen.

Ich sage nicht, dass es keine Situationen gibt, in denen
man abbrechen muss. Gegenbeispiel: Bei Clients mit einem Benutzer davor,
sollte man besser dem die Entscheidung überlassen.

> Gerade in der Netzwerkprogrammierung sind Timeouts fast unerlässlich.
> Häufig kann man sie allerdings an den TCP-Layer delegieren (z.B.
> SO_KEEPALIVE).

Wenn das sicher funktioniert, ist das wesentlich sinnvoller.
Oder man kann das Protokoll mit einer Keepalive-Funktion
ausstatten, wenn es von einem selber ist.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: alarm() unter Windows

am 16.01.2007 22:02:47 von Peter Arnhold

Frank Seitz schrieb:
> Peter J. Holzer wrote:
>> On 2007-01-15 18:51, Frank Seitz wrote:
>>> Sicher, aber macht es Sinn, gegen so eine Fehlersituation mit
>>> einem Timeout anzuprogrammieren?
>> Häufig ja.
>
> Ich bin skeptisch. Ich habe das noch nie gebraucht.

Dann hast Du das Glück, dass Du noch nie Anwendungen gestalten musstet, die
ohne fork oder Threads Nebenläufigkeit zu realisieren haben. Daraus zu
Schlussfolgern, dass das "normal" ist, halte ich für sehr gewagt.
Einfaches Gegenbeispiel: Anwendung mit Tk. Schlimm, wenn das Fenster nicht mehr
refreshed wird, weil ein Patchkabel fehlt.

Gruß,
Peter

Re: alarm() unter Windows

am 16.01.2007 22:38:16 von Frank Seitz

Peter Arnhold wrote:
> Frank Seitz schrieb:
>>Peter J. Holzer wrote:
>>>On 2007-01-15 18:51, Frank Seitz wrote:
>>>
>>>>Sicher, aber macht es Sinn, gegen so eine Fehlersituation mit
>>>>einem Timeout anzuprogrammieren?
>>>
>>>Häufig ja.
>>
>>Ich bin skeptisch. Ich habe das noch nie gebraucht.
>
> Dann hast Du das Glück, dass Du noch nie Anwendungen gestalten musstet, die
> ohne fork oder Threads Nebenläufigkeit zu realisieren haben. Daraus zu
> Schlussfolgern, dass das "normal" ist, halte ich für sehr gewagt.
> Einfaches Gegenbeispiel: Anwendung mit Tk. Schlimm, wenn das Fenster nicht mehr
> refreshed wird, weil ein Patchkabel fehlt.

....oder die Kommunikation einfach länger als wenige
Sekundenbruchteile dauert.

Du hast mich missverstanden. Meine Aussage bezog sich auf
den Abbruch einer TCP-Verbindung aufgrund einer willkürlich
festgelegten Zeitgrenze. Dass man auf I/O nicht immer
blockieren kann/will, ist eine andere Geschichte.

Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel

Re: alarm() unter Windows

am 18.01.2007 09:44:29 von Ferry Bolhar

Frank Seitz:

> Dem Prinzip nach musst Du hierzu einen
> Childprozess starten, den vom Parent aus überwachen und
> bei Zeitüberschreitung killen.

Genauso mache ich es jetzt auch: es wird gleichzeitig der Prozess,
der den "sc" Befehl ausführt, gestartet und ein zweiter, der einfach
eine vorgegebene Zeit wartet. Der erst legt in einem bestimmten
Verzeichnis eine Datei an, deren Namen u.a. seine PID enthält.
Wenn er mit seiner Arbeit fertig ist, löscht er die Datei wieder.

Der zweite schaut nach Ablauf der vorgegebenen Zeit nach, ob die
Datei noch existiert und falls das der Fall ist, holt aus den Namen
die PID, killt den betreffenden Prozess und löscht selber die Datei.

Nicht sehr elegant, ziemlich brutal (es muss sichergestellt werden,
dass Aufräumungsarbeiten, die normalerweise der erste Prozess
ausführt, dann vom zweiten erledigt werden), aber immerhin ein
Weg, der sicherstellt, dass das System nicht mit hängenden
Prozessen zugekleistert wird. Wie ich am Beginn des Threads
schon schrieb: "Feindliche Umgebung!". ;-)

Danke schön an alle, die sich hier zu Wort gemeldet haben, um
mir Tipps zu geben. Wer an dem Perl-Code beider Prozesse
interessiert ist, dem schicke ich ihn gerne zu.

LG, Ferry

--
Ing Ferry Bolhar
Magistrat der Stadt Wien - MA 14
A-1010 Wien
E-Mail: bol@adv.magwien.gv.at

Re: alarm() unter Windows

am 18.01.2007 11:48:30 von Peter Arnhold

Ferry Bolhar schrieb:
> Nicht sehr elegant, ziemlich brutal (es muss sichergestellt werden,
> dass Aufräumungsarbeiten, die normalerweise der erste Prozess
> ausführt, dann vom zweiten erledigt werden), aber immerhin ein
> Weg, der sicherstellt, dass das System nicht mit hängenden
> Prozessen zugekleistert wird. Wie ich am Beginn des Threads
> schon schrieb: "Feindliche Umgebung!". ;-)

Wenn Du mit fork arbeitest und nach dem Timeout ein
kill 'KILL', $pid;
aufrufst, bleibt nichts hängen. Da das sc vom Script gestartet wird, stirbt es
mit ihm nach dem kill.

Gruß,
Peter