Thread Verzögerte Ausführung von print-Befehlen (2 answers)
Opened by sas at 2009-12-12 23:20

sas
 2009-12-12 23:20
#129267 #129267
User since
2009-12-12
3 Artikel
BenutzerIn
[default_avatar]
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:

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
#!/usr/bin/perl -w

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?

View full thread Verzögerte Ausführung von print-Befehlen