in reply to (OT?) File Locking

Part of the rational for modern relational database was to solve the problems caused by race conditions and data corruption when using flat file databases that are accessed by mutiple processes simultaneously. Using a database allows the database to handle these issues for you so you might do well to consider that option.

That said this code should (probably :-) work OK for you:

#!/usr/bin/perl -w use strict; use POSIX ":sys_wait_h"; use Fcntl ':flock'; $|++; # set a timeout in second waiting for an exclusive lock my $timeout = 10; # in main body of code open file for append # filehandle will be available to all your kids open FH, ">>$file" or die "Can't open $file: $!"; my $pid = fork() die "Can't fork $!\n" unless defined $pid; unless ($pid) { # in a kid, get an exclusive lock on file my $tries = 0; until (flock FH, LOCK_EX|LOCK_NB) { sleep 1; die "Can't get exclusive lock $!\n" if $tries++ > $timeout } seek FH, 0, 2; # make sure we are at EOF print FH $blah; # safe to print here flock FH, LOCK_UN; # release lock for other kids exit; # kill kid } # wait for all kids to finish my $kids; do{ $kids = waitpid(-1, &WNOHANG) }until $kids == -1; close FH; # close file in parent

Update

Added seek FH, 0, 2 as per suggestion by dws

cheers

tachyon

s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Replies are listed 'Best First'.
(tye)Re2: (OT?) File Locking
by tye (Sage) on Apr 14, 2002 at 20:20 UTC

    For this code

    until (flock FH, LOCK_EX) { sleep 1; die "Can't get exclusive lock $!\n" if $tries++ > $timeout }
    either change LOCK_EX to LOCK_EX|LOCK_NB or just drop the whole loop counting retries because flock(FH,LOCK_EX) simply waits until the lock is obtained.

    Also, the seek isn't needed on any platform I know of. Windows needs the locking but already seeks each time you write to a file in append mode (though it certainly won't hurt). And I'd be sure to turn on "autoflush" for the file handle since you are using print to write the data.

            - tye (but my friends call me "Tye")