Perl (Version 5.10.1, unter Arch Linux) zeigt in Bezug auf die Ausführung von
print-Befehle folgendes sehr seltsames Verhalten:
Man sollte meinen, die Textausgabe des untenstehenden Perl-Skripts (an das Terminal in dem es aufgerufen wurde) würde folgendem zeitlichen Ablauf folgen (Zeilenumbrüche und Leerzeichen nicht aufgeführt):
[Sekunde 0]: "
do some processing:"
[Sekunde 1]: "
01"
[Sekunde 2]: "
02"
...
[Sekunde 24]: "
24"
[Sekunde 24]: "
do some more processing:"
[Sekunde 25]: "
01"
[Sekunde 26]: "
02"
...
[Sekunde 48]: "
24"
Stattdessen beobachte ich diese Abfolge:
[Sekunde 0]: "
do some processing:"
[Sekunde 10]: "
01 02 03 04 05 06 07 08 09 10"
[Sekunde 20]: "
11 12 13 14 15 16 17 18 19 20"
[Sekunde 24]: "
21 22 23 24"
[Sekunde 24]: "
do some more processing:"
[Sekunde 25]: "
01"
[Sekunde 26]: "
02"
...
[Sekunde 48]: "
24"
In anderen Worten: Im einem der beiden Durchläufe werden die
print-Befehle welche keinen Zeilenumbruch enthalten nicht zu dem Zeitpunkt ausgeführt, zu dem sie erteilt werden, sondern erst beim nächsten
print-Befehl, der einen Zeilenumbruch enthält.
Hier das Perl-Skript:
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
my @numbers = (1..24);
print "do some processing:\n";
traverseNumbers( \&doSomeProcessing );
print "do some more processing:\n";
traverseNumbers( \&doSomeMoreProcessing );
sub traverseNumbers {
my($function) = @_;
$count = 0;
for (0 .. $#numbers) {
$number = $numbers[$_];
if (&$function($number)) {
if($count % 10 == 0) { print " "; }
print sprintf(" %02d",$number);
if($count % 10 == 9) { print "\n"; }
$count = $count + 1;
}
}
print "\n";
}
sub doSomeProcessing {
my($number) = @_;
sleep(1);
return 1;
}
sub doSomeMoreProcessing {
my($number) = @_;
`sleep 1`;
return 1;
}
sleep(1) kann dabei durch beliebigen Code ersetz werden, der eine gewisse Zeit in Anspruch nimmt, und dabei
keine externen Programme aufruft (z.B.große Dateien einlesen und schreiben, viele komplizierte reguläre Ausdrücke verarbeiten, usw...) - es ändert alles nichts an der seltsamen Verzögerung der
print-Ausgaben.
`sleep 1` kann durch beliebige externe Programmaufrufe ersetzt werden - die
print-Ausgaben erfolgen in diesem Fall genau wie man sie erwarten würde, also eins nach dem anderen.
Ich finde diese Phänomen der unerwünschterweise verzögerten Ausgabe recht irritierend und vollkommen unerklärlich...
Kann mir jemand sagen, ob ich irgend etwas falsch mache, das dies auslösen könnte? Oder ist das ein Bug in Perl?