Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I'm working on some perl code that runs in a vareity of environments. In some cases, the files it needs to modify are on a local hard disk. In other cases, they are on an NFS mount. Since the script spawns multiple children that sometimes might try to modify a file at the same time, I need to implement some kind of file locking so they don't step on each other's toes. I've always read the flock() won't work over NFS. The key here, though, is that the script has no way of knowning whether the files it's working with are local or NFS-mounted. Is there something like flock() that will work regardless of whether the files are local or not?

Thanks!

Replies are listed 'Best First'.
Re: File Locking w/wo NFS
by PodMaster (Abbot) on May 28, 2004 at 15:24 UTC
    Is there something like flock() that will work regardless of whether the files are local or not?
    Yes, it's called flock ;) File::NFSLock File::FlockDir

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: File Locking w/wo NFS
by sgifford (Prior) on May 28, 2004 at 16:24 UTC
    fcntl will lock appropriately across NFS:
    #!/usr/bin/perl -w use strict; use Fcntl qw(F_WRLCK SEEK_SET F_SETLKW); open(F,"+< $ARGV[0]") or die "Couldn't lock myself: $!\n"; my $args = pack("sslli",F_WRLCK,SEEK_SET,0,0,$$); fcntl(F,F_SETLKW,$args) or die "Couldn't lock: $!\n"; print "File locked\n"; sleep(1000);
    note that the arguments to fcntl (in the pack statement) are system-specific.

    IIRC, compiling Perl with its own flock (instead of using the OS-provided one) will use an implementation built on top of fcntl, which should be NFS-safe, simpler to use, and more portable.

Re: File Locking w/wo NFS
by cees (Curate) on May 28, 2004 at 19:19 UTC

    An alternative to file locking is to use atomic updates. I'm pretty sure that NFS supports an atomic rename, so you could use IO::AtomicFile to edit your file, and guarantee that no two processes will write to the file at the same time.

    This will prevent file corruption, but it won't guarantee that you won't overwrite a change that was made by another process (ie there is a race condition from the time you read the file to when it gets written and renamed). So it might not be exactly what you need.

    - Cees