Which Counter is Perfect?

N

nntp

Counter 1: from Perldoc

use Fcntl qw:)DEFAULT :flock);
sysopen(FH, "numfile", O_RDWR|O_CREAT) or die "can't open numfile:
$!";
flock(FH, LOCK_EX) or die "can't flock
numfile: $!";
$num = <FH> || 0;
seek(FH, 0, 0) or die "can't rewind
numfile: $!";
truncate(FH, 0) or die "can't truncate
numfile: $!";
(print FH $num+1, "\n") or die "can't write
numfile: $!";
close FH

Counter 2:

01: #!/usr/bin/perl -w 02: use strict;
03: use Fcntl qw:)flock); 04: my $COUNTER = 'count.dat';
05: my $SEMAPHORE = $COUNTER . ".lock"; 06: print
qq{Content-Type: text/html\n\n}; 07: open(LOCK, ">$SEMAPHORE") or die
"Can't open $SEMAPHORE ($!)";
08: flock(LOCK, LOCK_EX); 09: open(DATA, $COUNTER) or die
"Can't open $COUNTER ($!)";
10: my $count = <DATA>;
11: close DATA; 12: $count++; 13: open(DATA,
"+<$COUNTER") or die "Can't open $COUNTER ($!)";
14: print DATA $count;
15: close DATA;
16: close LOCK; 17: print qq{You are number
$count!};Logically, Counter 2 looks perfect, but why would perldoc uses a
flawed counter? I also don't understand the difference of seek(FH, 0, 0)
or die "can't rewind numfile: $!"; truncate(FH, 0)
or die "can't truncate numfile: $!";and open ">$filename";
 
S

Sam Holden

Counter 1: from Perldoc

use Fcntl qw:)DEFAULT :flock);
sysopen(FH, "numfile", O_RDWR|O_CREAT) or die "can't open numfile:
$!";
flock(FH, LOCK_EX) or die "can't flock
numfile: $!";
$num = <FH> || 0;
seek(FH, 0, 0) or die "can't rewind
numfile: $!";
truncate(FH, 0) or die "can't truncate
numfile: $!";
(print FH $num+1, "\n") or die "can't write
numfile: $!";
close FH

Counter 2:

01: #!/usr/bin/perl -w 02: use strict;
03: use Fcntl qw:)flock); 04: my $COUNTER = 'count.dat';
05: my $SEMAPHORE = $COUNTER . ".lock"; 06: print
qq{Content-Type: text/html\n\n}; 07: open(LOCK, ">$SEMAPHORE") or die
"Can't open $SEMAPHORE ($!)";
08: flock(LOCK, LOCK_EX); 09: open(DATA, $COUNTER) or die
"Can't open $COUNTER ($!)";
10: my $count = <DATA>;
11: close DATA; 12: $count++; 13: open(DATA,
"+<$COUNTER") or die "Can't open $COUNTER ($!)";
14: print DATA $count;
15: close DATA;
16: close LOCK; 17: print qq{You are number
$count!};Logically, Counter 2 looks perfect, but why would perldoc uses a
flawed counter? I also don't understand the difference of seek(FH, 0, 0)
or die "can't rewind numfile: $!"; truncate(FH, 0)
or die "can't truncate numfile: $!";and open ">$filename";

The second one is simply madness. Why use a seperate lock file when
the counter file will do? Why open a file in read-write mode when you
are only writing to it?

It also fails to protect the count if the flock fails and hence
can't be called "perfect".

The second one has far more flaws than the first.

Please post code in a readable format and not the gunk that is quoted above.
 
N

nntp

The second one is simply madness. Why use a seperate lock file when
the counter file will do? Why open a file in read-write mode when you
are only writing to it?

It also fails to protect the count if the flock fails and hence
can't be called "perfect".

The second one has far more flaws than the first.

Please post code in a readable format and not the gunk that is quoted above.

You need to read http://www.perlguy.com/articles/locking.html
to understand why the second one is perfect, as far as it stated. I am not
an expert, but his statement makes sense.
 
S

Sam Holden

You need to read http://www.perlguy.com/articles/locking.html
to understand why the second one is perfect, as far as it stated. I am not
an expert, but his statement makes sense.

The only reason a seperate lock file is used in those examples is
because the count file is opened once for reading and then once for
writing. Sane people open it once for read-write and hence don't need
a second file for locking as the lock isn't lost during the
read->write reopen.

And it isn't "perfect", I already gave the case in which data corruption
results.

If you are not expert how do you know his statement makes sense?
 
N

nntp

:)
:) You need to read http://www.perlguy.com/articles/locking.html
:) to understand why the second one is perfect, as far as it stated. I am not
:) an expert, but his statement makes sense.

That article never claims the counter found in perldoc is wrong.

The second isn't perfect at all. It fails to work if the flock fails
(and that's possible!). Furthermore, it only patches one of the silly
things of the base program he starts with, instead of removing it all
together. His basic program opens the data file twice - once for reading,
once for writing. That's not necessary at all, and instead of fixing it
by not doing it, he just patches around it.


Abigail

Do you claim that the counter in Perldoc is Perfect? Do you see it covers
all cases?

sysopen(FH, "numfile", O_RDWR|O_CREAT);
flock(FH, LOCK_EX);
$num = <FH> || 0;
seek(FH, 0, 0) ;
truncate(FH, 0);
(print FH $num+1, "\n");
close FH;

I can not see how it can write and read at the same time. I don't understand
why it use sysopen, not open +<;
 
S

Sam Holden

Do you claim that the counter in Perldoc is Perfect? Do you see it covers
all cases?

It's unlikely to be perfect. In a world of TIMTOWTDI and people of
differing opinions "perfection" is next to impossible.

It's a much better solution for the problem at hand than the code on
that web site. The version that doesn't have the error checking removed
covers all the cases, where "all" is restricted to "I want to increment a
count in a text file".
sysopen(FH, "numfile", O_RDWR|O_CREAT);
flock(FH, LOCK_EX);
$num = <FH> || 0;
seek(FH, 0, 0) ;
truncate(FH, 0);
(print FH $num+1, "\n");
close FH;

I can not see how it can write and read at the same time. I don't understand
why it use sysopen, not open +<;

O_RDWR means read and write access. A simple perldoc -f sysopen would tell
you that.

The sysopen() version works if the file doesn't exist, whereas the open()
version will fail. Whether that is a good thing or a bad thing will depend
on the situation (see the "perfection" garbage above). I'd say in most
cases it's a good thing and useful for sample code as it will "just work".
 
G

Gunnar Hjalmarsson

The spontaneous answer to the question in the subject line that comes
up in my mind is: None.

As regards counters that are used for e.g. displaying visits at web
pages, it's important to understand that caching etc. makes the result
not exactly reflect the real visits. But something I personally find
more important is that the value of a counter, that just accumulates
visits, is limited. To me, it's more relevant to focus on the
*current* traffic. This is an example of a Perl counter written with
that view in mind:

http://www.gunnar.cc/programs/counter.pl.txt

For obvious reasons, that code is a little longer than the two
examples you posted, but OTOH it results in more meaningful (IMO)
info. For an example of what it outputs, see the bottom left of
http://www.gunnar.cc/quotes.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top