Lock Files, Part 2

Record Locking

To avert the problems associated with the file locking mechanism

presented last week (http://www.itworld.com/nl/lnx_tip/03082002/),

POSIX introduced record locking via the fcntl() syscall (the pre-POSIX

lockf() and flock() syscalls provide the same functionality but under

Linux, they are implemented as wrappers of the fcntl() syscall).

Record locking differs from file locking in two aspects: first, two or

more processes can access the same file as long as they're updating

different parts of it. For example, process A can lock the first 100

bytes of a file while another process is updating bytes 200-300.

Secondly, the kernel holds record locks, not by a process. Therefore,

when a process terminates, all its locks are automatically released.

Record Lock Types

There are two types of record locks: read locks (also called "shared

locks") and write locks (also called "exclusive locks"). Multiple

processes can lock the same file portion for read without conflicting

with each other. However, only one process at a time can hold a write

lock to a certain file region (note that write locks held by the same

process never conflict, even if the regions they lock coincide).

fcntl() is declared in

as follows: int fcntl(int fd, int command, long arg); The first argument is a descriptor of the file to be locked. The second argument can be one of the following: F_SETLK -- sets the lock. If the locking operation fails, EAGAIN is returned. F_SETLKW -- similar to F_SETLK except that it blocks until the lock is granted. F_GETLK -- Checks if the lock would be granted, without actually locking the record. If the lock cannot be obtained, the pid of the locking process is returned. The third argument is a pointer to the following struct: struct flock { short l_type; short l_whence; off_t l_start; off_t l_len; pid_t l_pid; }; The field l_type can be one of three values: F_RDLCK for a shared lock, F_WRLCK for an exclusive lock, or F_UNLCK for releasing an existing lock. l_whence indicates the position of the lock's start. It can be one of the values: SEEK_SET, SEEK_CUR, and SEEK_END. l_start indicates the offset relative to l_whence. l_len is the number of bytes to lock and l_pid holds the process's pid. For example, the following function attempts to get a write lock for the first 100 bytes of a file: int getlock(int fd) { int stat; struct flock lock; lock.l_type=F_RDLCK; lock.l_whence=SEEK_SET; /*file's beginning*/ lock.l_start=0;/*start at offset 0 from SEEK_SET*/ lock.l_len=100; lock.l_pid=getpid(); if(stat=fcntl(fd, F_SETLK, &lock)==0) printf("successfully locked"); else printf("failed"); return stat; }
ITWorld DealPost: The best in tech deals and discounts.