1. Perl
  2. File input/output
  3. here

Lock the file using the lock file

You can also create a lock file and lock it. The advantage of creating a file for file locking and performing exclusive control is that the file to be updated can be deleted or renamed.

The following example is a modification of the previous example to use a lock file. The script for the loop is exactly the same as last time. Save the locking script as example_20080815.pl and the loop script as data_20080815.txt.

Please refer to the previous example for the execution method.

use strict;
use warnings;
use Fcntl qw /:DEFAULT :flock :seek/;

# File for lock (create if not)
my $lock_file = "lock";
sysopen(my $lock_fh, $lock_file, O_RDONLY | O_CREAT)
  or die "Cannot open $lock_file:$!";

# Exclusive lock for lock file (exclusive lock because it is read and written)
flock($lock_fh, LOCK_EX)
  or die "Cannot lock $lock_file:$!";

# Be careful as it will be overwritten
my $file = "data_20080815.txt";

# Open in read/write mode (not very secure)
# If there is no file with O_CREAT, create it.
sysopen(my $fh, $file, O_RDWR | O_CREAT)
  or die "Cannot open $file:$!";

my $cnt;
$cnt = <$fh>;
if (! Defined $cnt && $!) {Die "Cannot read $file:$!";}

$cnt ++;

# Move the file pointer to the beginning
seek ($fh, 0, SEEK_SET)
  or die "Cannot seek $file:$!";

# write in.
print {$fh} $cnt
  or die "Cannot Write $file:$!";

# Truncate the file to write size
truncate ($fh, length $cnt);

close $fh
  or die "Cannot close $file:$!";

# The file lock is released at the time of close.
close $lock_fh
  or die "Cannot close $lock_file:$!";

print "Current count: $cnt\n";

(Reference) sysopen function, flock function, Fcntl

Loop script

use strict;
use warnings;
use FindBin;

my $script = "$FindBin::Bin/example_20080815.pl";

while (1) {
  system("perl $script");
  
  # Random number less than 1
  my $random = rand 1;
  sleep $random;
}

The script is repeatedly executed using while statement.

(Reference) FindBin, rand function

Code explanation

(1) Create a lock file

# Lock file (Note that it will be overwritten)
my $lock_file = "lock";
sysopen(my $lock_fh, $lock_file, O_RDONLY | O_CREAT)
  or die "Cannot open $lock_file:$!";

Create a file for the lock.

(2) Lock the lock file using the flock function

The lock file is locked using flock function.

# Exclusive lock for lock file (exclusive lock because it is read and written)
flock($lock_fh, LOCK_EX)
  or die "Cannot lock $lock_file:$!";

Only the process that can lock this file should access the file to be updated. Following this lock, open the file to be updated and update the file.

(3) Unlock

# The file lock is released at the time of close.
close $lock_fh
  or die "Cannot close $lock_file:$!";

The lock is released by closing the lock file.

Related Informatrion