Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Turnstep presents a bunch of great information in his File Locking tutorial. However, there is at least one file locking technique which I have not seen anyone use on perlmonks. I'm not sure if that's because there's something wrong with it, or because I haven't been looking hard enough.

First, some background. As turnstep points out, this is Bad (tm):

open my $FH, ">the_file"; # zero-byte the file flock($FH, LOCK_EX); # and Then lock it...
And, since you need to give flock() a file handle, it's not completely obvious how to read, process, and then write a file while maintaining a lock on it. This is an example of how Not to do it:

open my $FH, "the_file"; # open for reading flock($FH, LOCK_SH); # lock it my @lines = <$FH>; # read it open $FH, ">the_file"; # open for writing: LOCK DROPPED. # Now someone else picks up the lock and finds an empty # file. When they're finished, flock($FH, LOCK_EX); # lock it again push @lines, "new line\n"; # process the lines print $FH for (@lines); # write them out close $FH; # close and drop lock
Turnstep's tutorial presented the standard technique to fix this: use a separate "semaphore file" to keep track of locking:

# Open a different file as a semaphore lock open my $SEM, ">the_file.semaphore"; flock($SEM, LOCK_EX); # lock it # then process the Real File open my $FH, "the_file"; my @lines = <$FH>; # read it # because we never fiddle with $SEM, we still have a lock open $FH, ">the_file"; # open for writing. push @lines, "new line\n"; # process the lines print $FH for (@lines); # write them out close $FH; # close the file close $SEM; # close and unlock semaphore
The main problem with this is, it "doesn't play well with others." If you are trying to cooperate with other programs which you have no control over, you may not have the luxury of being able to use a semaphore file with a different name.

To me, the solution to this seems obvious. But I haven't seen this on perlmonks before, so my paranoia makes me think there's something wrong with it. I use the file itself as its own "semaphore file." This should work fine, since flock() locks are only advisory, not forced locks (that is, you can choose to ignore them and the OS won't even slap you on the wrist for it).

# Open the file for locking purposes only open my $SEM, "the_file"; flock($SEM, LOCK_EX); # lock it # Process it open my $FH, "the_file"; my @lines = <$FH>; open $FH, ">the_file"; push @lines, "new line\n"; print $FH for (@lines); close $FH; close $SEM; # close and unlock semaphore
Now we don't have any race conditions, because we're not doing anything with the_file before we get the lock, and we're not dropping the lock before we're completely finished with processing the file. We also behave well in relation to other programs which may be acquiring locks on the same file. We aren't creating stray lock files lying around which may need to be cleaned up periodically. It seems better in almost every respect... but does it work?

Thank you for your comments on this.

Alan


In reply to A flock()alypse now by ferrency

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



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (2)
As of 2024-04-19 18:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found