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

i use this on scripts that run from cron so that multiple copies don't run at the same time:
BEGIN {
    use Fcntl qw(LOCK_EX LOCK_NB);
    open SELF, '<', $0 or die "Failed to open $0: $!";
    flock SELF, LOCK_EX | LOCK_NB  or exit;
}
i got a warning from perlcritic about bare filehandles so i converted it to a lexical variable, but then the flock stopped working. not sure why this doesn't work, because the pod for flock shows an example with a lexical variable:
BEGIN {
    use Fcntl qw(LOCK_EX LOCK_NB);
    open my $self, '<', $0 or die "Failed to open $0: $!";
    flock $self, LOCK_EX | LOCK_NB  or exit;
}
  • Comment on how to convert lexical filehand so flock will work with it

Replies are listed 'Best First'.
Re: how to convert lexical filehand so flock will work with it
by davido (Cardinal) on Jul 05, 2013 at 07:09 UTC

    The lexical filehandle fell out of scope, auto closed, and the flock was implicitly released. The problem isn't with flock, nor with lexical filehandles. It's a matter of coping with scoping. ;)


    Dave

      thanks, that makes sense.

        Perl::Critic is probably wrong on this one... or at least, insensitive to valid use cases. That's a frequent issue with Perl::Critic; while the book was intended to encourage thoughtfulness with respect to best practices, the module doesn't do a very good job of trying to understand why your situation might justify using an item that it considers to be a violation. The best practice really is to know what you're doing, and why. The rest is just food for thought.

        By the way, you may find this slide interesting: MJD "Only one process running at a time", from Mark Jason Dominus's File Locking Tricks and Traps talk.

        Update: I almost forgot to mention -- this employs the "lock the DATA filehandle" trick, and allows you to avoid dealing directly with flocking: Sys::RunAlone.


        Dave

Re: how to convert lexical filehand so flock will work with it
by kcott (Archbishop) on Jul 05, 2013 at 06:52 UTC

    As well as lexical filehandles, flock also shows how to die with a message which includes $! (see perlvar - Error Variables): that would be a good way for finding out what went wrong. It also has this which may be related to your problem:

    "... and it requires that FILEHANDLE be open with write intent."

    See also autodie.

    Please also post code in <code>...</code> tags, not <pre>...</pre> tags.

    -- Ken