The Linux Programming Interface

(nextflipdebug5) #1

1118 Chapter 55


Figure 55-1: Two processes updating a file at the same time without synchronization

The problem is clear: at the end of these steps, the file contains the value 1001,
when it should contain the value 1002. (This is an example of a race condition.) To
prevent such possibilities, we need some form of interprocess synchronization.
Although we could use (say) semaphores to perform the required synchronization,
using file locks is usually preferable, because the kernel automatically associates
locks with files.
[Stevens & Rago, 2005] dates the first UNIX file locking implementation to
1980, and notes that fcntl() locking, upon which we primarily focus in this
chapter, appeared in System V Release 2 in 1984.
In this chapter, we describe two different APIs for placing file locks:

z flock(), which places locks on entire files; and
z fcntl(), which places locks on regions of a file.

The flock() system call originated on BSD; fcntl() originated on System V.
The general method of using flock() and fcntl() is as follows:


  1. Place a lock on the file.

  2. Perform file I/O.

  3. Unlock the file so that another process can lock it.


Read seq. # (obtains 1000)

Process A Process B

time slice
expires

time slice
begins

time slice
begins

time slice
ends

Read seq. # (obtains 1000)

Use seq. #

Increment seq. # (to 1001)
and write back to file

Use seq. #

Increment seq. # (to 1001)
and write back to file

Executing
on CPU

Waiting
for CPU

Key
Free download pdf