R
Robert TV
Hi, I am asking foir advice on which form of code i've written below is the
correct and safe way to lock a file. I've done some reading on" use Fcntl
qwDEFAULT :flock);" and I understand the basics. I've also read back on
many posts regarding file locking and there seems to be much debate. For
this code, I simply want to increase a value.
#!/usr/bin/perl
use Fcntl qwDEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);
open (NUMBER, "<number.txt") or die "Can't open file: $!";
flock (NUMBER, LOCK_EX) or die "Can't lock file: $!";
$value = <NUMBER>;
close(NUMBER);
$value = $value++;
open (NUMBER, ">number.txt") or die "Can't open file: $!";
flock (NUMBER, LOCK_EX) or die "Can't lock file: $!";
print NUMBER $value;
close(NUMBER);
The above code seems to work ok. My question is when the first user locks
and reads the file, does the locking prevent other users from reading the
file? The $value is then increased and printed back to the file.
Another concern of mine is ... User#1 locks file, reads file value, then
close and releases lock. While User#1 is writing the new value back to the
file, another user came and read the unlocked file BEFORE the value was
increased. So he gets the same value as User#1. User#2 then increases the
value and writes the same data as User#1. In the end, the locking technique
failed ... am I right?
Another method I came up with is locking and entire read/write session
within a what I will call "parent lock" Here is the code:
#!/usr/bin/perl
use Fcntl qwDEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);
open (PARENT, "<locker.txt") or die "Can't open file: $!"; #an empty file
flock (PARENT, LOCK_EX) or die "Can't lock file: $!";
open (NUMBER, "<number.txt") or die "Can't open file: $!";
flock (NUMBER, LOCK_SH) or die "Can't lock file: $!";
$value = <NUMBER>;
close(NUMBER);
$value = $value++;
open (NUMBER, ">number.txt") or die "Can't open file: $!";
flock (NUMBER, LOCK_SH) or die "Can't lock file: $!";
print NUMBER $value;
close(NUMBER);
close(PARENT); #closes the parent lock
Now User #1 locks the parent file and moves on to the read/write session.
All other users get stuck back at the parent lock until released. I had to
use LOCK_SH for the read/write locks for some reason ... if all locks were
set to EX the program would stall. Is this technique better? Is it
effective? Or perhaps they are both ineffective?
In this next example, I don't want to increase a value, just append to the
file on a new line. So I do this:
#!/usr/bin/perl
use Fcntl qwDEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);
open (DATA, ">>locker.txt") or die "Can't open file: $!";
flock (DATA,LOCK_EX) or die "Can't lock file: $!";
print DATA "$data\n";
close(DATA);
Im going to assume that this is ok.
It's just when increasing a value that concerns me ... multipul users
reading same value when the read lock is released. Your suggestions are
greatly welcomes. TIA
Robert
correct and safe way to lock a file. I've done some reading on" use Fcntl
qwDEFAULT :flock);" and I understand the basics. I've also read back on
many posts regarding file locking and there seems to be much debate. For
this code, I simply want to increase a value.
#!/usr/bin/perl
use Fcntl qwDEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);
open (NUMBER, "<number.txt") or die "Can't open file: $!";
flock (NUMBER, LOCK_EX) or die "Can't lock file: $!";
$value = <NUMBER>;
close(NUMBER);
$value = $value++;
open (NUMBER, ">number.txt") or die "Can't open file: $!";
flock (NUMBER, LOCK_EX) or die "Can't lock file: $!";
print NUMBER $value;
close(NUMBER);
The above code seems to work ok. My question is when the first user locks
and reads the file, does the locking prevent other users from reading the
file? The $value is then increased and printed back to the file.
Another concern of mine is ... User#1 locks file, reads file value, then
close and releases lock. While User#1 is writing the new value back to the
file, another user came and read the unlocked file BEFORE the value was
increased. So he gets the same value as User#1. User#2 then increases the
value and writes the same data as User#1. In the end, the locking technique
failed ... am I right?
Another method I came up with is locking and entire read/write session
within a what I will call "parent lock" Here is the code:
#!/usr/bin/perl
use Fcntl qwDEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);
open (PARENT, "<locker.txt") or die "Can't open file: $!"; #an empty file
flock (PARENT, LOCK_EX) or die "Can't lock file: $!";
open (NUMBER, "<number.txt") or die "Can't open file: $!";
flock (NUMBER, LOCK_SH) or die "Can't lock file: $!";
$value = <NUMBER>;
close(NUMBER);
$value = $value++;
open (NUMBER, ">number.txt") or die "Can't open file: $!";
flock (NUMBER, LOCK_SH) or die "Can't lock file: $!";
print NUMBER $value;
close(NUMBER);
close(PARENT); #closes the parent lock
Now User #1 locks the parent file and moves on to the read/write session.
All other users get stuck back at the parent lock until released. I had to
use LOCK_SH for the read/write locks for some reason ... if all locks were
set to EX the program would stall. Is this technique better? Is it
effective? Or perhaps they are both ineffective?
In this next example, I don't want to increase a value, just append to the
file on a new line. So I do this:
#!/usr/bin/perl
use Fcntl qwDEFAULT :flock);
use CGI::Carp qw(fatalsToBrowser);
open (DATA, ">>locker.txt") or die "Can't open file: $!";
flock (DATA,LOCK_EX) or die "Can't lock file: $!";
print DATA "$data\n";
close(DATA);
Im going to assume that this is ok.
It's just when increasing a value that concerns me ... multipul users
reading same value when the read lock is released. Your suggestions are
greatly welcomes. TIA
Robert