Thread watchdog bei einer while-Schleife
(20 answers)
Opened by perlensammler22 at 2015-09-22 07:29
Hi,
ich wollt es selber mal ausprobieren... Zunächst ein simples Skript, um alle X Sekunden einen Output zu generieren: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #! /usr/bin/env perl use strict; use warnings; use Getopt::Long; $| = 1; # unbuffered STDOUT GetOptions( \my %OPT, 'interval=i', ) or exit 255; die "(E) No interval specified.\n" unless $OPT{interval}; while ( 1 ) { print scalar(localtime), "\n"; sleep $OPT{interval}; } __END__ Dann ein Skript, welches über die Argumente genannt bekommt, von welchem Programm es lesen soll und wie lange es dauern soll, bis ein Timeout vorliegt: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #! /usr/bin/env perl use strict; use warnings; use Getopt::Long; $| = 1; # unbuffered STDOUT # save command and cmdline arguments for later re-use # because GetOptions modifies @ARGV my @cmdline = ( $0, @ARGV ); GetOptions( \my %OPT, 'timeout=i', ) or exit 255; die "(E) No timeout specified.\n" unless $OPT{timeout}; my @command = @ARGV; my $pid = open my $pipe, '-|', @command or die "(E) Could not open pipe to command '@command': $!"; print "pid $pid : @command\n"; while ( 1 ) { my $line; # read from $pipe; must be successful within $OPT{timeout} seconds eval { local $SIG{ALRM} = sub { die "alarm\n"; }; alarm $OPT{timeout}; $line = <$pipe>; alarm 0; }; # timeout exceeded if ( $@ ) { die "(E) error in alarm...\n" if $@ ne "alarm\n"; print "ALARM received!\n"; exec( @cmdline ) or die "(E) Could not re-execute myself: $!"; } # just in time else { print "READ: $line"; } } __END__ Der Aufruf dann als: Code: (dl
)
./readstream --timeout 3 -- ./datastream --interval 5 Mit -- endet die Optionsliste für readstream; alles was danach kommt, wird für das auszuführende Kommando verwendet; hier also ./datastream --interval 5. datastream soll nur alle 5 Sekunden eine Ausgabe liefern, und readstream soll schon nach 3 Sekunden einen Timeout melden. Resultat: Code: (dl
)
1 pid 4964 : ./datastream -int 5 Alle 5 Sekunden kommt die Ausgabe von datastream; aber schon nach 3 Sekunden meldet sich der alarm mit der Timeout Meldung. Mit der exec()-Zeile wird dann das Skript selber nochmal aufgerufen (man beachte die steigende PID für datastream bei den Ausgaben). Die PID für readstream bleibt dabei dieselbe (beachte ![]() meine Beiträge: I.d.R. alle Angaben ohne Gewähr und auf Linux abgestimmt!
Die Sprache heisst Perl, nicht PERL. - Bitte Crossposts als solche kenntlich machen! |