Re: I can't flock, it returns 0, any ideas.

From: Guy (someone_at_somewhere.nb.ca)
Date: 12/01/03


Date: Mon, 01 Dec 2003 17:43:47 GMT

WOW!!!
Thanks to everyone for all the information.
I will try to put all or at least most of these suggestions to use.

With respect to flock, my perl 5 book says it returns 1 if true, and '' if
false, whatever that means.
In any case, I changed one thing and now it appears to work.

open(LCKFILE,"$lockfil"); # returns zero when I try to flock
open(LCKFILE,">$lockfil"); # returns one when I try to flock

As for the parsing, I thought it would be more portable by doing it the long
way.
I guess it's from my older days of writing, or maybe I was just doing it
wrong back then too!

Thanks for putting so much time to this.
Cheers all.
Guy Doucet

"Ben Morrow" <usenet@morrow.me.uk> wrote in message
news:bqftdd$p18$1@wisteria.csv.warwick.ac.uk...
>
> "Guy" <someone@somewhere.nb.ca> wrote:
> > I can't flock, it returns 0, any ideas.
>
> man flock
>
> | RETURN VALUE
> | On success, zero is returned. On error, -1 is returned and
> | errno is set appropriately.
>
> This is what the syscall returns. Perl maps these values (0 and -1) to
> "0 but true" and undef respectively. The upshot of this is that if you
> say 'if (flock(...) == 0)' it will always be true: "0 but true" numifies
> to 0, as does undef. The correct test is 'if (flock(...))': undef is
> false, and "0 but true" is true (that's why Perl uses that special
> string rather than the number 0).
>
> > I wanted to run this script to see if it would affect my other perl
script
> > whi is trying to access the same file.
>
> Note that flock() locks are advisory, so it won't affect your other
> script unless that also uses flock. The rules governing locks are:
>
> 1. Locks don't affect anything except other locks: they don't stop
> anyone opening, reading, writing, deleting, etc. the file.
>
> 2. You can only hold a lock on an open file. (The details of what
> happens when you have several handles open on the same file depend
> on the underlying system: don't go there. :)
>
> 3. If someone holds a LOCK_EX lock, all attempts to get a lock will
> fail. (LOCK_EX means 'exclusive lock'.)
>
> 4. If someone holds a LOCK_SH lock, attempts to get a LOCK_EX lock
> will fail but attempts to get another LOCK_SH lock will
> succeed. (LOCK_SH means 'shared lock'.)
>
> 5. If you can't get the lock you are trying for, then if you specify
> LOCK_NB (use | rather than +, i.e. 'flock $FH, LOCK_SH | LOCK_NB)
> the flock call will fail, and if you don't flock will just not
> return until you can.
>
> > From what I read, I'm assuming that when you close a file, it also
unlocks
> > it, so I'm guessing that you don't really have to unlock it before
closing
> > it.
>
> That's right. Most uses of LOCK_UN are wrong.
>
> > I tried 1,2, and 8, but it doesn't appear to lock the file, and the
flock
> > function returns 0.
>
> Don't do this. Use the constants from Fcntl, both for readability and
> portability:
>
> > #!/usr/local/bin/perl -w
> >
> > use CGI qw(:standard);
>
> use Fcntl qw/:flock/;
>
> > no warnings;
>
> Why? Using '-w' and then 'no warnings' is particularly perverse... You
> should have both these lines:
> use warnings;
> use strict;
> and then you don't need '-w'.
>
> > print header();
> >
> > $fd="../data";
>
> my $fd = "../data";
>
> Insert 'my' similarly for all the variables 'strict' complains about.
>
> > $lockfil="$fd/lock.txt";
> >
> > $temp=$ENV{'QUERY_STRING'};
> > @pairs=split(/&/,$temp);
> >
> > foreach $item(@pairs)
> > {
> > ($key,$content)=split(/=/,$item,2);$CONFILTERED=~tr/+/
> > /;$CONFILTERED=~s/%(..)/pack("c",hex($1))/ge;
> > if($key eq "f"){$f=$content;}
> > if($key eq "l"){$l=$content;}
> > }
>
> NO. Since you're using CGI.pm, *USE* it. Read the docs if you don't
> know how: perldoc CGI.
>
> > print"<HTML><BODY>\n";
> >
> > $gchk=locksys(); # Lock file access
>
> [Indentation sorted out: you'll find code much easier to work with if
> you indent properly]
>
> > if($gchk==0) {
>
> So here you just want
> if($gchk) {
>
> > while($f>0) {
> > $f--;
> > $t=64000;
> > while($t>0) {
> > $t--;
> > $a = 1234;
> > $b = 31;
> > $c = $a * $b / 3;
> > }
> > }
>
> AARGH! No no no, this is not how you pause the script!
> See 'perldoc -f sleep'.
>
> > &unlocksys;
>
> Don't use &sub unless you know what it does and why you need it:
> unlocksys();
>
> > }
> >
> > print"Done!<BR></BODY></HTML>\n";
> >
>
> [more indentation-adjusting]
>
> > sub locksys{
> > my $chk=3840;
> > if(-d "$fd") {
> > $chk=3584;
> > if(open(LCKFILE,"$lockfil")) {
>
> This will fail if lock.txt doesn't exist. Since you're just using it
> for locking, you can just nuke it each time with
> open LCKFILE, ">$lockfil";
> .
>
> > $chk=flock LCKFILE,$l;
>
> This is silly. You don't need to pass the type of lock to aquire in as
> a CGI parameter. Those programs which only read whatever it is you are
> locking should use
> $chk = flock LCKFILE, LOCK_SH;
> and those that write should use
> $chk = flock LCKFILE, LOCK_EX;
> . The rules given above were designed with this in mind. If you are
> just trying to make sure you have only one copy of your script running
> at a time, use LOCK_EX.
>
> > }
>
> If the open failed, don't you want to know why? Perl will tell you if
> you ask it nicely:
> else {
> print "Open failed: $!";
> }
>
> I would be very much inclined to structure this whole thing rather
> differently. I would have:
>
> sub locksys {
> my $file = shift;
>
> open my $FH, ">", $file or die "can't open lockfile: $!";
> flock $FH, LOCK_EX or die "can't aquire lock: $!";
>
> return $FH;
> }
>
> There are several points here:
>
> 1. 'my $file = shift' means we take the file to lock as an argument.
>
> 2. 'my $FH' creates a what is called a 'lexical filehandle'. Basically
> this means that the file is automatically closed as soon as all
> references to it go out of scope, so you don't need &unlocksys any
> more.
>
> 3. We return this filehandle from the sub, so that the file isn't just
> closed straight away (that would be rather silly). You use it like
> this:
>
> #...program...
>
> {
> my $LOCK = locksys("../data/lock.txt");
>
> #... do stuff that relies on having the lock
> }
> #... $LOCK goes out of scope here, so the file is closed and the lock
> # lost.
>
> 4. If any of the syscalls fails, we 'die'. This will terminate the
> program with an error message. You can use the CGI::Carp module
> (see its docs) to get the error sent somewhere sensible when
> running CGI scripts.
>
> This is really a matter of style: you could just as well choose to
> return undef or something instead, and write your own error message
> with $! up in the main script. You may find this approach easier if
> you want to fail softly rather than aborting the script and don't
> feel like messing with eval {}.
>
> 5. I assume here that if flock fails it is a fatal error. If flock may
> fail non-fatally (either because you used LOCK_NB or because your
> system doesn't restart syscalls if you catch a signal) you will
> need to investigte the Errno module to find the reason for its
> failure, and take appropriate action.
>
> Ben
>
> --
> perl -e'print map {/.(.)/s} sort unpack "a2"x26, pack "N"x13,
> qw/1632265075 1651865445 1685354798 1696626283 1752131169 1769237618
> 1801808488 1830841936 1886550130 1914728293 1936225377 1969451372
> 2047502190/' #
ben@morrow.me.uk



Relevant Pages

  • Re: I cant flock, it returns 0, any ideas.
    ... > I can't flock, it returns 0, any ideas. ... You can only hold a lock on an open file. ... will fail but attempts to get another LOCK_SH lock will ... this is not how you pause the script! ...
    (comp.lang.perl.misc)
  • Re: [PHP] usage of flock
    ... > I am confused with the flock function and its usage. ... > hoping the first job_controller will lock it-self, ... if the server crash down the "surviving" lock file ... locked file from an "exit" or killed script, and then you have to know ...
    (php.general)
  • Re: [PHP] usage of flock
    ... to use flock. ... hoping the first job_controller will lock it-self, ... I also thought of writing in the lock file the PID of the first ... So how could prevent multiple instance of the same script? ...
    (php.general)
  • Re: PHP instances writing to the same file?
    ... to lock a file if you are running your script on a server with an OS ... Here is a flock sample from: ... In my case a single PHP script appends text strings to an existing text ...
    (comp.lang.php)
  • Re: File Locks...
    ... E.G. firewalls logs can be "copied" while in use when using ... You could autostart a wbem script to monitor file change in a dir ... > remove a file lock condition. ...
    (microsoft.public.scripting.wsh)