2

If I run the following script in parallel I could see few are waiting for acquiring lock but some are running in parallel. LOCK_EX is not working as expected. I don't understand what is missing here.

$|++;
my $lockHandle;
my $file='lock.txt';
#sysopen( $lockHandle, $file, O_RDWR|O_CREAT);
open($lockHandle, '>>', $file);
print "aquiring lock\n";
my $o = flock $lockHandle,LOCK_EX or die "Could not lock '$file' - $!";
print "Locked....$o\n";

## Only executes when the lock is acquired

my $count=5;
my $intex=0;
while ($index <= $count){
   print "executing\n";
   sleep 1;
   $index=$index+1;
}
END {
 flock $lockHandle, LOCK_UN;
 close $lockHandle;
 unlink $file;
 }
xxfelixxx
  • 6,512
  • 3
  • 31
  • 38
  • 1
    Are you using [strict](https://perldoc.pl/strict)? Are you using [Fcntl](https://perldoc.pl/Fcntl)? – choroba May 09 '22 at 18:26
  • With proper `use strict` (and fixing errors related to this) and `use Fcntl ':flock'` I cannot reproduce what you are reporting. My guess is that the problem is due to blindly using undefined `LOCK_*` which then basically are no-op's. – Steffen Ullrich May 09 '22 at 18:37
  • @Steffen Ullrich, Not no-ops. `LOCK_EX` becomes equivalent to `"LOCK_EX"`, which `flock` treats as `0`. The `flock` is effectively a noop, though (returning error EINVAL). – ikegami May 09 '22 at 19:15

1 Answers1

3

For starters, ALWAYS use use strict; use warnings;! It would have found your problem.

You forgot to import the constants LOCK_EX and LOCK_UN, which you can do using

use Fcntl qw( LOCK_EX LOCK_UN );

(O_RDWR and O_CREAT would similarly need to be imported from the same module, if you were to use them.)

You end up passing the string LOCK_EX or LOCK_UN instead of the values the constants with those names represent. This is why the program dies with Invalid argument.

ikegami
  • 367,544
  • 15
  • 269
  • 518