Schrift
[thread]6418[/thread]

Zeitgesteuerte abarbeitung (Seite 2)



<< |< 1 2 >| >> 12 Einträge, 2 Seiten
Gast Gast
 2004-07-21 20:07
#84675 #84675
Habe das gerade mal getestet:
Code: (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
#!/usr/bin/perl

   use strict;
   use warnings;
   
   my $run_time = time;
   my $duration = 48; # Stunden
   my $interval = 0,
   my ($cnt, $the_time);
   
   my @interval = (2, 4, 8, 10); # Minuten
   
   my $sub = sub {
       my $cnt = shift;
       open FILE, "> AbsolutePath/log_file.dat" or die $!;
       print FILE $cnt . "\n";
       close FILE;
   };

   $sub->(1);
   
       while ((time - $run_time) <= ($duration * 3600)) {            
           $the_time = (time - (stat("AbsolutePath/log_file.dat"))[9]);

           $the_time < $interval
               ?   do {
                       sleep(($interval - $the_time));
                       next;
                   }
               :   do {
                       # für diesen Zweck sollte
                       do "AbsolutePath/cgi-bin/the_script.pl" or die $!;
                       # ausreichend sein - wenn nicht dann mit fork() oder system() arbeiten
                       
                       $interval = (shift(@interval) * 60);
                       push @interval, ($interval / 60);
                       $sub->($cnt++);
                   }
       }        

ist nicht das 'gelbe vom Ei' aber es scheint zu funktionieren.
Edit: mit the_script.pl ist das auszuführende Programm gemeint\n\n

<!--EDIT|Dieter|1090488494-->
Dubu
 2004-07-23 15:41
#84676 #84676
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=Guest,20.07.2004, 19:00]
Das Script soll 2000 mal innerhalb von 36 oder 48 Stunden
in unregelmäßigen abständen wie ca. 5M. dann mal 10M.
dann wieder evtl. 8M oder so ähnlich eine Funktion aufrufen.
[/quote]
36 Stunden sind 2160 Minuten. Wenn du die Aktion einfach jede Minute ausfuehrst, bist du also schon ziemlich nah an deinen 2000 mal. Abstaende von mehreren Minuten waeren daher mehr als ueberdurchschnittlich lang. Da muss man eher in Sekunden messen.

Mein Ansatz waere, zuerst in einer Art Monte-Carlo-Methode 2000 Zeitpunkte innerhalb der verfuegbaren Zeitspanne festzulegen und diese dann abzuarbeiten:
Code: (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
#!/usr/bin/perl
use strict;
use warnings;

my $cnt = 2000;      # Gesamtanzahl
my $hours = 36;      # Gesamtzeit in Std


my $time = $hours * 60 * 60;      # Gesamtzeit in Sekunden
die "Zu viele Zeitpunkte!" if $cnt > $time; # Sonst gaebe es eine Endlosschleife!

print "Durchschnittliche Wartezeit der Events: ", $time/$cnt, " Sek.\n";

my %evt_table;         # Ereigniszeitpunkte

# $cnt Events auswuerfeln
for (1 .. $cnt) {
   my $evt = int(rand($time));
   redo if $evt_table{$evt}; # Schon besetzt? => Neu
   $evt_table{$evt} = 1;
}

# Testausgabe der Zeitpunkte
# print "$_ " for sort { $a <=> $b } keys %evt_table;


my $t0 = time();      # Startzeitpunkt
print "Start um ", scalar(localtime($t0)), "\n";

for (sort { $a <=> $b } keys %evt_table) {
   my $delay = ($t0 + $_) - time();  # Wartezeit
   sleep $delay if $delay > 0;       # wenn Wartezeit, dann schlafen

   ### Hier Event ausloesen
   print "Event mit Zeit $_ um ", scalar(localtime()), "\n";
   ###
}

Die Methode hat den Vorteil, dass wirklich immer die gewuenschte Anzahl an Events abgearbeitet wird (sofern ueberhaupt moeglich) und die Eigendauer der einzelnen Events wenig ins Gewicht faellt, weil das Delay zum naechsten Event jeweils neu berechnet wird. Sollten Events zu kurz aneinander gelegen haben, so werden sie damit so schnell wie moeglich hintereinander ausgefuehrt.
<< |< 1 2 >| >> 12 Einträge, 2 Seiten



View all threads created 2004-07-20 21:00.