Click the aboveblue text to follow us
Linux file locking is a mechanism used to manage resource access in multi-process or multi-threaded environments, ensuring that only one process or thread can operate on a file at a specific time, thus avoiding data inconsistency.
File locks are widely used in various applications, such as database systems, file sharing systems, and log management.
Linux provides several file locking mechanisms, including flock, fcntl, and lockf, each with its own advantages, disadvantages, and applicable scenarios.
1
Using flock() for file locking
flock is one of the simplest file locking methods in Linux, providing the ability to lock the entire file.
flock only provides an “advisory lock,” meaning it is only effective for processes that adhere to this mechanism and does not forcibly prevent other processes from accessing the file.
The function prototype is as follows:
int flock(int fd, int operation);
Parameter description:
fd: File descriptor used to specify the file to be locked.operation: Type of operation used to control the locking method:
- LOCK_SH: Shared lock, allowing multiple processes to read the same file, but not write.
- LOCK_EX: Exclusive lock (write lock), ensuring that only one process can write to the file.
- LOCK_UN: Unlock operation, releasing the lock.
- LOCK_NB: Non-blocking lock flag, used in combination with LOCK_SH or LOCK_EX. If the lock cannot be acquired immediately, it returns an error and sets errno to EWOULDBLOCK.
Return value: Returns 0 on success, -1 on failure and sets errno.
Usage example:
int fd = open("example.txt", O_RDWR);if (flock(fd, LOCK_EX | LOCK_NB) == -1) { perror("Failed to lock the file"); // Handle lock failure}// Perform file operationsflock(fd, LOCK_UN); // Unlock
Notes on flock():
- flock only supports locking the entire file and cannot lock a specific part of the file.
- Since it is an advisory lock, other processes that do not use file locks can still access the file content.
2
Using fcntl() for file locking
fcntl provides a more flexible file locking mechanism, including the ability to lock specific regions of a file and supports both advisory and mandatory locks.
Compared to flock, fcntl is more complex and powerful.
The function prototype is as follows:
int fcntl(int fd, int cmd, ... /* struct flock *flockptr */ );
Commands related to locks:
F_GETLK: Checks if there are lock conflicts on the file. It updates the struct flock pointer’s value based on the current lock status of the file.F_SETLK: Non-blocking lock. Used to add or remove locks; if the lock fails, it returns immediately.F_SETLKW: Blocking lock. If the lock cannot be acquired immediately, the process will wait until the lock is available.
struct flock structure:
struct flock is used to describe the details of the lock:
l_type: Type of lock, can be set to F_RDLCK (read lock, shared lock), F_WRLCK (write lock, exclusive lock), or F_UNLCK (unlock).l_whence、l_start、l_len: Used to define the offset and length of the locked region, similar to the offset and whence parameters in the lseek() function.l_pid: Process ID of the lock holder, mainly used to detect file lock conflicts (F_GETLK).
Usage example:
int fd = open("example.txt", O_RDWR);struct flock lock;lock.l_type = F_WRLCK; // Set write locklock.l_whence = SEEK_SET;lock.l_start = 0; // Start locking from the beginning of the filelock.l_len = 0; // Lock the entire file// Attempt to lockif (fcntl(fd, F_SETLK, &lock) == -1) { perror("Failed to lock the file"); // Handle lock failure}// Perform file operationslock.l_type = F_UNLCK; // Unlockfcntl(fd, F_SETLK, &lock);
Advanced features and notes on fcntl():
- File region locking: Supports locking specific regions of a file, suitable for applications requiring high precision locking.
- Mandatory locks: Can be configured as mandatory locks, which will block access to processes that do not adhere to the locking mechanism.
- Dynamic lock range: If l_len is set to 0, the lock range will extend from l_start to the end of the file, and the lock area will also extend as the file grows.
3
Using lockf() for file locking
lockf is a wrapper function for fcntl, simplifying its usage.
lockf essentially relies on fcntl for implementation, supports file region locking, but does not support mandatory locks.
The function prototype is as follows:
int lockf(int fd, int cmd, off_t len);
cmd: Controls the locking or unlocking behavior:
- F_LOCK: Blocking lock.
- F_TLOCK: Non-blocking lock.
- F_ULOCK: Unlock.
- F_TEST: Test if it can be locked.
len: Specifies the length of the locked region. Setting it to 0 means locking to the end of the file.
Usage example:
int fd = open("example.txt", O_RDWR);if (lockf(fd, F_LOCK, 0) == -1) { perror("Failed to lock the file"); // Handle lock failure}// Perform file operationslockf(fd, F_ULOCK, 0); // Unlock
lockf is suitable for simple file locking needs, especially when locking the entire file region.
However, its functionality is limited compared to fcntl and is typically used in scenarios where precise control is not particularly required.
The file locking mechanisms in Linux provide a flexible solution for multi-process concurrency control.
flock is simple and suitable for locking entire files, while fcntl is more flexible, allowing for locking specific regions of a file and supporting blocking/non-blocking operations.
lockf, as a wrapper for fcntl, simplifies operations and is suitable for simple locking needs.
Choosing the appropriate locking mechanism based on specific application requirements is key to achieving efficient file management.
Clickto read the original article for more exciting content~