Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Ensuring only one copy of a perl script is running at a time

by Moron (Curate)
on Dec 19, 2006 at 16:54 UTC ( [id://590700]=note: print w/replies, xml ) Need Help??


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

As I understand it, the first argument to flock must be a filehandle. So the fact that the tricky use of __DATA__ works on unix seems better characterised as an unclosed loophole and your own solution as the correct version that accords with the manual.

-M

Free your mind

  • Comment on Re: Ensuring only one copy of a perl script is running at a time

Replies are listed 'Best First'.
Re^2: Ensuring only one copy of a perl script is running at a time
by ikegami (Patriarch) on Dec 19, 2006 at 17:38 UTC

    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.

      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.
      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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://590700]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2024-04-19 09:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found