your example does not use an external lock file...i'll just leave it at that.
...one other thing i noticed with the original poster's code is that it's closing the counter file and then opening it again, which is just plain asking for trouble, as it all should be done under one lock. anyway, i got the camel book out:
use Fcntl qw(:DEFAULT :flock);
$lockfile = "counter.lck";
sysopen(COUNTERLOCK, $lockfile, O_RDONLY | O_CREAT) or die "can't open
+ $lockfile: $!";
flock(COUNTERLOCK, O_EXCL) or die "can't lock $lockfile: $!";
....here open your counter file in read/write mode using same locking semantics as per the lockfile...then seek to 0, read the integer, add 1, seek to 0, write new value, close counter file, close lockfile, output new value to screen. don't unlock the counterfile/lockfile, just close them. this flushes the buffers and releases locks and closes in a fairly atomic fashion....that's another bug in the original code. Just remember that all this locking is only advisory, and programs not written to respect the locks will clobber it. Also, don't try to lock files over any network file systems, such as NFS,SMBFS.