Schrift
[thread]712[/thread]

flock funktioniert nicht (Seite 5)



<< |< 1 2 3 4 5 6 7 >| >> 65 Einträge, 7 Seiten
Dubu
 2006-04-18 19:25
#7375 #7375
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Mooooment!

Jetzt bitte nicht syswrite() in die Diskussion einbringen, das ist eine komplett andere Baustelle als sysopen() vs. open()! Und der Offset-Parameter bei syswrite() hat absolut nix mit einem seek() in einer Datei zu tun, der betrifft nur die auszugebende Variable!
Dubu
 2006-04-18 19:27
#7376 #7376
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=master,18.04.2006, 15:27]das problem ist, das ">" oder "<" ne datei anlegt, falls sie nicht exisitert.[/quote]
Ein open() mit "<" legt keine Datei an. Wäre ja auch Unsinn, eine Datei neu anzulegen, die man nur lesen möchte.
master
 2006-04-18 20:00
#7377 #7377
User since
2003-10-20
610 Artikel
BenutzerIn
[default_avatar]
@Dubu

Naja beim open bzw. "Print" kannst du nicht an eine bestimmte stelle schreiben, ohne seek beim syswrite (hanlder, wert, lenght, offset) schon, das meinte ich als Vorteil.


< = ja hast recht... bei so intensivem diskutieren passieren halt mal fehler.. ganz klar > legt an, < liest aus.
$i='re5tsFam ^l\rep';$i=~s/[^a-z| ]//g;$\= reverse "\U!$i";print;
betterworld
 2006-04-18 20:20
#7378 #7378
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
[quote=pq,18.04.2006, 14:31]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
use Fcntl qw(:flock :seek);
open my $fh, "+<", "datei" or die $!;
flock $fh, LOCK_EX;
seek $fh, 0, SEEK_SET;
chomp(my $count = <$fh>);
$count++;
seek $fh, 0, SEEK_SET;
truncate $fh, 0;
print $fh "$count\n";
close $fh;
[/quote]
Sorry, dass ich mich auch noch einmische: Imho ist es in der zitierte Code nicht 100% sicher. Wenn direkt nach dem "truncate" der Prozess gekillt wird (z. B. wegen einem Server-Neustart), ist die Datei leer. Meine vorgeschlagene Loesung: In eine zweite (gelockte) Datei schreiben, und wenn man fertig ist, ein atomares rename() benutzen, um die alte Datei zu ersetzen.

Edit: Anmerkung: Dieses Vorgehen wuerde auch im Falle eines vollen Dateisystemes einer Korruption der Datei vorbeugen, wenn man die Rueckgabewerte von print und close ueberprueft.\n\n

<!--EDIT|betterworld|1145377953-->
ptk
 2006-04-19 00:21
#7379 #7379
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
[quote=master,18.04.2006, 16:47]Natürlich mit autoflush = 1
Code: (dl )
1
2
Zeit: 7    #sysopen
Zeit: 10 #open

[/quote]
Benchmark-Code?
betterworld
 2006-04-19 01:00
#7380 #7380
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
[quote=ptk,18.04.2006, 22:21][quote=master,18.04.2006, 16:47]Natürlich mit autoflush = 1
Code: (dl )
1
2
Zeit: 7    #sysopen
Zeit: 10 #open

[/quote]
Benchmark-Code?[/quote]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ perl -we 'use Benchmark;
use strict;
use Fcntl;
timethese(
5000000,
{
sysopen => sub {
sysopen( my $F, "datei", O_WRONLY ) or die $!
},
open => sub {
open( my $F, ">datei" ) or die $!
}
}
)'
Benchmark: timing 5000000 iterations of open, sysopen...
open: 57 wallclock secs (40.82 usr + 16.47 sys = 57.29 CPU) @ 87275.27/s (n=5000000)
sysopen: 54 wallclock secs (39.85 usr + 13.77 sys = 53.62 CPU) @ 93248.79/s (n=5000000)


Das sind dann umgerechnet ganze 0.6 Mikrosekunden Unterschied. Fuer jeden ressourcenbewussten Menschen sollte das ein klarer Grund sein, sysopen zu bevorzugen.

Nachtrag:
Code: (dl )
1
2
3
4
5
6
7
$ perl -v

This is perl, v5.8.7 built for i386-linux

Copyright [...]
$ uname -a
Linux cyan 2.6.17-rc1 #1 PREEMPT Thu Apr 13 02:24:34 CEST 2006 i686 Intel(R) Pentium(R) M processor 2.00GHz GenuineIntel GNU/Linux

Edit: Ein bisschen perltidy\n\n

<!--EDIT|betterworld|1145405646-->
Dubu
 2006-04-19 01:15
#7381 #7381
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Hm. Interessant, ich hatte eher die Größenordnung wie bei master heraus.
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
#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw/cmpthese/;
use Fcntl;

cmpthese (-5,
   {
       open    => sub {
           open FILE, ">", "open_vs_sysopen.tst" or die $!;
           close FILE;
       },
       sysopen => sub {
           sysopen FILE, "open_vs_sysopen.tst", O_CREAT|O_WRONLY or die $!;
           close FILE;
       },
   }
);
__END__
          Rate    open sysopen
open    58073/s      --    -29%
sysopen 81322/s     40%      --

$ perl -v

This is perl, v5.8.8 built for i486-linux-gnu-thread-multi

Ohne das close() ist der Unterschied sogar noch ein wenig größer, ohne das O_CREAT erst recht.

Ich habe auch mal deinen Code getestet, betterworld. Da sieht's genauso aus:
Code: (dl )
1
2
3
4
$ perl -we 'use Benchmark; use strict; use Fcntl; timethese(5000000,{sysopen=>sub{sysopen(my $F, "datei", O_WRONLY) or die $!}, open => sub {open(my $F, ">datei") or die $!}})'
Benchmark: timing 5000000 iterations of open, sysopen...
     open: 124 wallclock secs (53.82 usr + 62.77 sys = 116.59 CPU) @ 42885.32/s (n=5000000)
  sysopen: 84 wallclock secs (51.25 usr + 28.48 sys = 79.73 CPU) @ 62711.65/s (n=5000000)

Kommt wohl auch auf die Perl-Version/Plattform an.
Dubu
 2006-04-19 01:22
#7382 #7382
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=master,18.04.2006, 18:00]Naja beim open bzw. "Print" kannst du nicht an eine bestimmte stelle schreiben, ohne seek beim syswrite (hanlder, wert, lenght, offset) schon, das meinte ich als Vorteil.[/quote]
Nur zur Klarstellung: Man kann open() mit syswrite() benutzen und genauso sysopen() mit print(). Man darf nur nicht print() und syswrite() auf einem Filehandle vermischen.

Vielleicht habe ich mich oben nicht klar genug ausgedrückt:
1.)  Du brauchst auch bei syswrite() ein vorheriges seek(), wenn du an eine bestimmte Stelle in einer Datei schreiben willst!
2.) Der Offset bei syswrite() hat nichts mit dem Offset bei seek() zu tun! Bei syswrite() gibt man den Offset in der auszugebenden Variablen an, nicht in der Datei.
ptk
 2006-04-19 02:06
#7383 #7383
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Ich wollte es zuerst dem -thread-multi in die Schuhe schieben. Aber vielleicht ist doch Linux schuld? Die Ergebnisse unter FreeBSD:
Code: (dl )
1
2
3
4
5
6
7
8
           Rate sysopen    open
sysopen 12801/s -- -3%
open 13188/s 3% --

perl5.8.8 -v

This is perl, v5.8.8 built for i386-freebsd
(with 1 registered patch, see perl -V for more detail)

Und mit einem threadfähigen Perl:
Code: (dl )
1
2
3
4
5
6
7
          Rate    open sysopen
open 7566/s -- -2%
sysopen 7706/s 2% --

perl5.8.7t -v

This is perl, v5.8.7 built for i386-freebsd-thread-multi

Im niedrigen einstelligen Prozentbereich diskutiert man bei Benchmarks eh' nicht...
betterworld
 2006-04-19 05:15
#7384 #7384
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Weil der von mir gegebene Code immer die Datei mit dem Namen "datei" anlegt (wobei man die Datei vorher selbst anlegen sollte, wenn man sysopen ohne O_CREAT verwendet), habe ich den Code immer mit /tmp als Arbeitsverzeichnis laufen lassen. Einmal habe ich vergessen, "cd /tmp" zu machen und somit lief er im Home-Verzeichnis. Dreimal duerft Ihr raten, was ich rausgefunden habe: Im Home-Verzeichnis gibt es reproduzierbar deutlich andere Ergebnisse als in /tmp! (Man muss erwaehnen, dass /home bei mir ext3 ist und /tmp ist tmpfs.)

Die Ergebnisse in /tmp sind immer ungefaehr wie oben (54 fuer sysopen, 58 fuer open), in ~ sind sie hingegen immer ungefaehr 54 fuer sysopen, 70 fuer open.


Ferner habe ich noch probiert, was passiert, wenn man bei sysopen nicht nur O_WRONLY sondern O_WRONLY|O_CREAT|O_TRUNC angibt (das ist genau das, was open auch macht, siehe strace). Das Ergebnis ist erschuetternd: Nun braucht sysopen länger als open! Circa 65 Sekunden fuer 5000000 Durchläufe auf tmpfs und ca. 80 auf ext3.

Hier noch einmal als Uebersicht:
Code: (dl )
1
2
3
4
5
                                     |  ext3  |  tmpfs
=======================================================
open | 70 | 58
sysopen (O_WRONLY) | 54 | 54
sysopen (O_WRONLY|O_CREAT|O_TRUNC) | 80 | 65

Was mich vor allem wundert, ist, dass der Unterschied zwischen open und sysopen(O_WRONLY|O_CREAT|O_TRUNC) sich je nach Dateisystem unterschiedlich stark äußert. Ein Blick in strace zeigt naemlich beide Male dieselben System-Calls, und außerhalb von System-Calls sollte sich das Dateisystem eigentlich nicht auswirken...

Ich bin jetzt etwas zu muede, um weiter zu experimentieren.\n\n

<!--EDIT|betterworld|1145410044-->
<< |< 1 2 3 4 5 6 7 >| >> 65 Einträge, 7 Seiten



View all threads created 2006-04-17 19:11.