Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re: Mysterious Disapperance of file contents

by aquarium (Curate)
on Aug 29, 2003 at 02:27 UTC ( #287571=note: print w/replies, xml ) Need Help??


in reply to Mysterious Disapperance of file contents

you're not supposed to open, and then lock your lock/semaphore file, as in that gap of time, another copy of your program can open it also. any decent perl book (e.g. camel book) tells you how to get around it. Alternatively, read the docs and faqs on open and flock.
  • Comment on Re: Mysterious Disapperance of file contents

Replies are listed 'Best First'.
Re: Re: Mysterious Disapperance of file contents
by BrowserUk (Pope) on Aug 29, 2003 at 03:05 UTC
    you're not supposed to open, and then lock your lock/semaphore file...

    As someone unfamiliar with flock semantics, could you explain how your comments sits with the example given in the docs for flock:

    use Fcntl ':flock'; # import LOCK_* constants sub lock { flock(MBOX,LOCK_EX); # and, in case someone appended # while we were waiting... seek(MBOX, 0, 2); } sub unlock { flock(MBOX,LOCK_UN); } open(MBOX, ">>/usr/spool/mail/$ENV{'USER'}") or die "Can't open mailbox: $!"; lock(); print MBOX $msg,"\n\n"; unlock();

    and with flock taking a filehandle? Doesn't that mean I have to open it before I lock it?

    I'm blissfully unaware or "how you're supposed to do it", using different mechanisms for this purpose, but I find the documentation decidedly unclear. Care to explain it?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

      Keep in mind you can't use LOCK_UN safely because of buffering. Use close() for that.

        Is that still true--I asked in total ignorance--given this from perlfunc:flock?

        To avoid the possibility of miscoordination, Perl now flushes FILEHANDLE before locking or unlocking it.

        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
        If I understand your problem, I can solve it! Of course, the same can be said for you.

      your example does not use an external lock file...i'll just leave it at that.
      ...one other thing i noticed with the original poster's code is that it's closing the counter file and then opening it again, which is just plain asking for trouble, as it all should be done under one lock. anyway, i got the camel book out:
      use Fcntl qw(:DEFAULT :flock); $lockfile = "counter.lck"; sysopen(COUNTERLOCK, $lockfile, O_RDONLY | O_CREAT) or die "can't open + $lockfile: $!"; flock(COUNTERLOCK, O_EXCL) or die "can't lock $lockfile: $!";
      ....here open your counter file in read/write mode using same locking semantics as per the lockfile...then seek to 0, read the integer, add 1, seek to 0, write new value, close counter file, close lockfile, output new value to screen. don't unlock the counterfile/lockfile, just close them. this flushes the buffers and releases locks and closes in a fairly atomic fashion....that's another bug in the original code. Just remember that all this locking is only advisory, and programs not written to respect the locks will clobber it. Also, don't try to lock files over any network file systems, such as NFS,SMBFS.
        don't unlock the counterfile/lockfile, just close them. this flushes the buffers and releases locks and closes in a fairly atomic fashion....that's another bug in the original code.

        Modern versions of Perl flush file buffers before locking or unlocking a file. This is even documented.

        Abigail

        I don't quite understand why to use sysopen. The same trouble Gorby has now, I had about two years ago (CGI counter resets for no obvious reason). Later I modified my counting system to something similar to your example. It obviously works, but if it's "bad" code I surely want to understand why and improve it. Here it is:
        #! /usr/bin/perl use Fcntl ':flock'; open(Z,"+<count.txt")||&neu; flock(Z,LOCK_EX); $z=<Z>; $z++; seek (Z,0,0); print Z "$z\n"; flock(Z,LOCK_UN); close(Z); print "Status: 204 No Response\n\n"; exit(0); sub neu {open(Z,">count.txt"); print Z "0\n"; close(Z); open(Z,"+<coun +t.txt");}
Re: Re: Mysterious Disapperance of file contents
by bobn (Chaplain) on Aug 29, 2003 at 02:45 UTC

    That was my first thought, (hence my award-winning post above), but after reading the doc on flock, it appears that purpose of the flock isn't to stop the second program from opening the file - instead it stops the second program from obtaining the lock - the second program's flock(HANDLE, LOCK_EX) blocks until the first program issues flock(HANDLE, LOCK_UN).

    The doc on flock shows a sequence much like that used by the OP, but without use of a spearate seamphore file.

    Testing things very similar to the OP's code seems to work as expected. I don't see the issue.

    --Bob Niederman, http://bob-n.com

    All code given here is UNTESTED unless otherwise stated.

Re: Re: Mysterious Disapperance of file contents
by sgifford (Prior) on Aug 29, 2003 at 02:47 UTC
    That's just wrong. flock and fcntl both take a filehandle as their first argument. How are you supposed to provide a filehandle without opening a file first?

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2020-06-02 10:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Do you really want to know if there is extraterrestrial life?



    Results (17 votes). Check out past polls.

    Notices?