Really irritating, I know I saw it listed as a bug, but I cannot find reference to it now. In general on a properly working Unix system, yes. Writes go to a buffer that gets flushed to the kernel whenever. From the kernel it gets flushed to disk whenever. (You don't want your program waiting on your disk drive. Really. Unless you are a database, know exactly what you are doing, and are looking for solid transactional semantics...)

If you manually flush the buffer (see select for how to do this) then in theory that goes to the kernel (or over NFS goes to the server) and you don't return from that until after the change is globally visible. So flushing your buffer and then unlocking should be safe. Indeed page 246 of the Perl Cookbook claims that as of Perl 5.004 there is an automatic flush when you unlock a filehandle. perldoc -f flock agrees with that. (So the importance of a manual flush is more important to know for when you are working in other languages.)

But I do have a memory wandering around that I cannot track down right now saying that theory != practice in some situations on some operating systems. (What, you mean that some OSs have bugs??? Yup!) I don't have a reference though. :-(

However if you scan for "dual-buffer" in this summary of what is new in Linux 2.4 you will find that there used to be separate read and write buffers in the Linux kernel. I know that led to bugs, I don't know if any of those are applicable here. (If you also look for mentions of "raw device" you will find that raw I/O devices are mentioned. If you have a database on Linux and it is not on a raw I/O device, then it cannot give perfectly protected transactional support as I mentioned above.)

There is a bug I have encountered on Windows that may relate but which just relying on close is not enough. I found when working in a directory mounted remotely through SMB that if I wrote and closed a file, then *immediately* run a system command that accessed that file, occasionally my write was not visible. If I put in a delay then it never failed.

There may be all sorts of system specifics needed to hit it, and even where it happened it was only occasional. The fact that these bugs depend on the install was driven home for me by another one I reported then eventually just worked around. rename on NT will set case if the filesystem understands it. But if the effect only changes the case of an existing file, then depending on your exact dlls, the kernel may delete the file instead. This is only seen on some installs of NT. Specifically it did not happen in testing or on any machine for a year until we got some new desktops in and then lost a bunch of files...

But back to your question. I am fairly sure that I have seen a bug report where it really was better to just close the file, don't try to flush and unlock first. But in theory there is no reason why that could ever be true. And I cannot find the example right now.

ObRandomTrivia: flock may not work on all filesystems even if it is supported in the OS. I know that the Linux folks in particular don't support it, and a lot of databases (eg Oracle, Berkeley DB) say and really mean that they are not to be run off of NFS partitions.


In reply to (tilly) : Can't find it :-( 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.