Maelstrom has asked for the wisdom of the Perl Monks concerning the following question:
I have a long running script that logs it's process to a file and an FCGI that reads said file every 200ms when prompted to by ajax calls and it seems to mostly work but occasionally fails. I believe I've recreated the problem with the following 2 SSCCE's
one.pl
use Fcntl qw (:DEFAULT :flock :seek); my $file = '/dev/shm/tmpcount.txt'; for (1 .. 180) { print "$_\n"; &filewrite($file,$_); sleep 1; } sub filewrite { my ($file,$enc) = @_; open(my $fh,">", $file) || die "Can't open $file for reading: $!"; my $mode = LOCK_EX; flock($fh,$mode) or die "Couldn't lock $file for write"; print $fh $enc; close $fh; }
two.pl
use Fcntl qw (:DEFAULT :flock :seek); my $file = '/dev/shm/tmpcount.txt'; my $c; do { if (-e $file) { $c = &fileread($file); die "C is empty" unless ($c); print "count is $c \n"; } else { print "File not found\n"; } } until ($c == 180); sub fileread { + # Read using perl IO my $file = shift; open(my $fh, "<", $file) || die "Can't open $file for reading: $!"; my $mode = LOCK_SH; flock($fh,$mode) or die "couldn't lock"; my $string = do { local $/; <$fh> }; close $fh; return $string; }
When I use warn instead of die the script appears to work, as it is it will invariably complain that $c is empty at some point. What I think is happening is one.pl opens the file and truncates it but before it gets to calling flock two.pl swoops in and reads an empty file. I suppose the obvious solution is semaphores but as I'm trying to develop a "safe" file handling library I'm wondering if there's another way to go about it. My first thought was an atomic open and lock with sysopen but apparently linux can't do that. I'm wondering if opening the file readwrite and truncating after flock would solve this or would possible race conditions remain? I'm aware if multiple processes are doing read-mutate-write then a semaphore lock is the only way to go but I'm curious if 1 writing and 1 reading process can work without them.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Vexing Race Condition
by tybalt89 (Monsignor) on May 01, 2025 at 15:44 UTC | |
by Maelstrom (Beadle) on May 02, 2025 at 02:17 UTC | |
Re: Vexing Race Condition
by NERDVANA (Priest) on May 03, 2025 at 16:43 UTC | |
Re: Vexing Race Condition
by ikegami (Patriarch) on May 02, 2025 at 10:16 UTC | |
Re: Vexing Race Condition
by Marshall (Canon) on May 02, 2025 at 19:58 UTC | |
by tybalt89 (Monsignor) on May 02, 2025 at 21:42 UTC | |
by Maelstrom (Beadle) on May 03, 2025 at 13:45 UTC | |
by tybalt89 (Monsignor) on May 03, 2025 at 17:13 UTC | |
by Maelstrom (Beadle) on May 03, 2025 at 13:29 UTC | |
Re: Vexing Race Condition
by cavac (Prior) on May 05, 2025 at 14:14 UTC |