http://qs1969.pair.com?node_id=26707


in reply to RE: RE: RE: Flock Subroutine
in thread Flock Subroutine

Well, using anything incorrectly can lead to problems, but I still think a simple flock is best - just be careful about it.

> Here you should be able to see the race. Another process
> can get an exclusive lock on the FH during the read open
> (read-only opens don't generally get exclusive locks),
> and between the close of the read and open of the write.

I don't agree with this. First, if another process cannot get an exclusive lock while *any* other lock is on it. So if process A locks a file for reading (shared lock) and then process B tries to get an exclusive lock, process B cannot get the lock until *all* the locks are gone - shared and exclusive. In the second case, yes it's a problem, but that's a bad coding problem, not a problem with flock. The right way to do it of course is to open the file for read/write, get an exclusive lock, read in the file, rewind (usually), write to the file, and close it, releasing the exclusive lock.

  1. Proc A open FH for write (using > which clobbers the file contents)
  2. Proc B opens FH for reading (no lock attempt since it won't likely get an exclusive lock granted)
  3. Proc A locks FH
  4. Proc A works with FH
  5. Proc A closes FH

No need for a semaphore, just change the above a bit:

  1. Proc A opens FH for read/write (the file is not changed at all yet)
  2. Proc B opens FH for reading (and gets a shared lock)
  3. Proc A locks FH exclusively, after B has released it's shared lock
  4. Proc A works with FH
  5. Proc A closes FH

And yes, I need to update my tutorial. :)

Replies are listed 'Best First'.
RE: RE: RE: RE: RE: Flock Subroutine
by KM (Priest) on Aug 08, 2000 at 17:29 UTC
    Sure, there are flows which are less likely to cause a race condition. But, I am a realist and know many novice programmers can't see a race condition if they are staring at it, and semaphore files take the race out of the condition (sorry, it is bad pun day). Not all processes want to open files for read/write. Some may want only append, or only clobber. By using semaphores, you can avoid trying to have to figure out if you are making a race condition (or worse, finding out the hard way). I prefer the offensive mode of programming when any type of security issue may be involved, such as file locking and race conditions. You see code put on this site where race conditions would happen, so you can see many people do not think of it or recognize it. To each his/her own, but I know my files won't be currupt with semaphores :)

    Cheers,
    KM

      Many experienced programmers do not understand races either. For instance every select() loop has a race condition - between you being notified and you trying to respond, the data may have gone. Early versions of Apache suffered from this problem, one request could tie up several children.

      A related bug warning. The examples in the documentation and in the Perl Cookbook of using flock with DB_File are not safe. It was discovered last fall that the first page of the database is read before you have a chance of locking the dbm, and in some cases BerkeleyDB will close and reopen the file behind your back.

        This is why good ole whiteboards and a bunch of cow orkers are helpful. Knowing flow, seeing possible conditions, and knowing tidbits about software. Of course, using a semaphore file should solve these issues, since you take the actual locking piece away from the wanted data set. For example, if you lock a semaphore before opening the DBM, the DBM can close and reopen all it wants, since the semaphore is the lock.

        Cheers,
        KM