This is an excellent point, and it is easier to get in trouble than you might think looking at the gap in the code.

Control of it is held at the OS level. If someone else has a flock waiting on your file, as soon as you drop your flock and lose your time slice, they get the flock and go. However the OS lies to you. You can have written output, and flushed buffers, and all that means is that the OS knows what it still has to do for you, but it has not necessarily actually happened yet. So if you do your write, drop your lock, they get control, open, and read, your write may not be visible to them.

Now you say that this is unbelievably unlikely. And it doesn't happen that often. But if you have critical data, then you probably have little tolerance for the possibility. Besides which while it is unlikely that the flock will be when you lose your time slice on a single-processor system, with SMP it is far more likely to happen. Why? Because before the kernel can drop your lock it has to make sure that all of the processors are aware of the change, and that means that your flock causes a wait on what other processors are doing. Because of that wait, when your flock is done it is not at all unlikely that you have hit the end of your time-slice. Which means that it is not at all unlikely (on SMP machines) that you will be interrupted between the flock and the close. And if that happens while someone else is waiting on the lock and they get scheduled next, their time slice can easily be long enough to grab a chunk of the file...

So as c-era correctly says, the right way to do this is just call close with the lock still held. Then the OS will know to flush all internal buffers before, dropping the filehandle, and in cleanup will drop the lock safely. And done this way there is no possible miscoordination of buffers to mess you up.

There is a moral and general principle here. Whenever you have an opportunity (not just with locks) to push the responsibility for synchronizing stuff down to a layer that thinks it is in control, do so. Doing that means less work for you, less opportunity for you to make a mistake, less possibility that the lower layer will make a bad assumption, etc.

This applies to file locking (push it off to the OS), writing loops (push it off to Perl), installing software (push it off to your package manager - at least this is good advice with Debian), and so on.


In reply to Re (tilly) 2: flock - lordy me.... by tilly
in thread flock - lordy me.... by agoth

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.