Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Atomic operation

by willjones (Sexton)
on Jul 20, 2009 at 16:58 UTC ( #781689=perlquestion: print w/replies, xml ) Need Help??

willjones has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I have a situation where I believe I need some sort of atomic action protection for a section of code. I have a small file with a single value in it that is read by my CGI code and then checked for a specific value. If the value is not found then the file is updated to contain the value and a set of code is run and then execution ends. If the value is found then a different set of code is run (the file is not updated at all) and execution ends. My concern is what will happen if two CGI requests were to hit almost simultaneously so that the code that checks my file for the specific value occurs in the second thread before the first has a chance to update the file which would otherwise cause the second thread to be blocked from running that code. I came across flock here and wondered if this would be the most appropriate solution for my situation or not. From what I read flock may or may not actually lock the file depending on the OS? Is this something I should be concerned with?

Does the following code make sense? Can I read and write after specifying LOCK_SH (or do I have to unlock and then re-lock with LOCK_EX?) Should this work if two processes were to hit my code at the same time?
#Lock my file... # Use LOCK_SH because I don't want the second thread to be able # to read until I'm done. flock( OUTFILE, LOCK_SH); seek( OUTFILE, 0, 2); # Why do I need this line? # Read from OUTFILE and if it has the right value then go ahead and # write the new value into it to indicate that the second process # should do something different, otherwise you are the second # process... unlock and do something different. # Now unlock... flock( OUTFILE, LOCK_UN);

Replies are listed 'Best First'.
Re: Atomic operation
by jethro (Monsignor) on Jul 20, 2009 at 17:47 UTC
    This is exactly the situation where flock makes sense. But I think you need LOCK_EX. EX stands for "exclusive" while SH stands for "shared". If you had lots of data to read before the write it might make sense to first use LOCK_SH (prevents others to get LOCK_EX, but doesn't prevent the LOCK_SH of other readers). But since you do a quick test+optional write, LOCK_SH probably wastes more time than it saves on simultaneous reads.

    So my advice: Just do your operation between a LOCK_EX and a LOCK_UN.

    Linux and most other unixes work with flock, but you should avoid nfs-mounted partitions. It is probably best to include a test in your code if you anticipate the program to use different OSes

    UPDATE: the seek in your example code seeks to the end of the file. Not a good idea if you want to read it or rewrite it, only good for appending.

      Works fine in Windows too.
        I believe the semantics on Windows differ slightly from *nix. (On Unix locks are advisory, on Windows they are mandatory.) Also the semantics on *nix vary based on the filesystem. (NFS is different than remote Windows is different from local filesystem.)

        Which underscores the importance of having a unit test.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://781689]
Approved by ikegami
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (1)
As of 2020-10-25 02:48 GMT
Find Nodes?
    Voting Booth?
    My favourite web site is:

    Results (248 votes). Check out past polls.