http://www.perlmonks.org?node_id=590717


in reply to Re: Ensuring only one copy of a perl script is running at a time
in thread Ensuring only one copy of a perl script is running at a time

The problem is that Windows uses mandatory locking, while unix uses advisory locking. It has nothing to do with DATA. Perl doesn't check if the file is locked, so advisory locks are completely ignored. However, when mandatory locking is involved, perl can't read the source file when it's locked.

DATA is a filehandle to the file being executed. It's well known that one can seek to offset 0 of DATA to read the source code. Locking DATA is the same thing as locking the file whose name is in $0. It doesn't matter how you lock the script (using DATA or $0 (as shown below)), the problem still exists.

use strict; use warnings; use Fcntl qw(:flock); print "start of program\n"; open(my $script_fh, '<', $0) or die("Unable to open script source: $!\n"); unless (flock($script_fh, LOCK_EX|LOCK_NB)) { print "$0 is already running. Exiting.\n"; exit(1); } print "sleeping 15...\n"; sleep(15); print "end of program\n"; __DATA__ This exists so flock() code above works. DO NOT REMOVE THIS DATA SECTION.

Update: Updated the non-code portion for clarity.

Replies are listed 'Best First'.
Re^3: Ensuring only one copy of a perl script is running at a time
by sruthikuppam (Initiate) on Mar 24, 2011 at 05:24 UTC
    While executing the above script the contents of the given file in the script gets deleted.WHY????
      I don't know what you are talking about. The script neither takes a file nor does it delete or even write anything.
Re^3: Ensuring only one copy of a perl script is running at a time
by Moron (Curate) on Dec 19, 2006 at 17:57 UTC
    The fact that locking behaviour differs in general by platform is not relevant because (see manual link labelled 'it' in earlier reply) flock deliberately uses its own advisory locking irrespective of platform precisely for such reasons of portability.

    -M

    Free your mind

      I find extremely rude posts that do nothing but contradict the parent when the poster could have verified that the parent was correct.

      You're wrong. flock does NOT use its own advisory locking. If flock implemented some kind of advisory locking, Windows's type command would know nothing of it, yet it can't read a file locked using flock.

      use Fcntl qw( :flock ); open(my $fh, '>', 'file') or die("Unable to open file: $!\n"); print $fh ("ok\n"); print("type without lock:\n"); system("type file"); print("\n"); flock($fh, LOCK_EX|LOCK_NB) or die("Unable to lock file: $!\n"); print("type with lock:\n"); system("type file"); unlink('file');

      outputs

      >perl 590735.pl type without lock: ok type with lock: The process cannot access the file because another process has locked +a portion of the file.

      Tested with 5.6.0, 5.6.1, 5.8.0 and 5.8.8.

      Update: Updated to show that type works when the file isn't locked by flock.

        It seems the point is that flock is documented to have behavior that varies between platforms. If flock is documented as always providing advisory locking, then I think that is a documentation bug (it reads to me that it certain may provide only advisory locking, but I didn't find a clear statement that manditory locking isn't the result on some platforms -- it quickly points to perlport, in fact).

        So, if flock is documented to behave differently on different platforms, then writing code that depends on flock being advisory is not portable (which it obviously isn't, in practice).

        It looks to me like you missed the point. And I don't see where any technical point was "just refuted" when it could have just been checked by Moron. But I certainly could be missing something.

        - tye