Refer to the differences between FCNTL (), LOCKF, flock in Linux
What is the difference between these three functions , which are all about locking up a file?
First flock and fcntl are system calls, and LOCKF is a library function . LOCKF is actually a fcntl package , so the bottom-level implementation of LOCKF and Fcntl is the same, and the effect on file locking is the same. In the latter case, the Fcntl and LOCKF are put together in most cases when different points are analyzed.
The following first look at the use of each function, from the way and effect of use to see the difference between the various functions.
1. Flock
L Function prototypes
#include <sys/file.h>
int flock (int fd, int operation); Apply or remove an advisory lock on the open file specified by FD, just a suggested lock
Where FD is the file descriptor returned by the system call open, the options for operation are:
Lock_sh: Shared lock
LOCK_EX: Exclusive lock or exclusive lock
Lock_un: Unlock.
LOCK_NB: Non-blocking (used with three operations above)
With regard to the flock function, it is first important to know that the flock function can only lock the entire file, not a portion of the file, which is the first significant difference in FCNTL/LOCKF, which can lock a region of the file.
second, flock can only produce an advisory lock . We know that Linux has a forced lock (mandatory lock) and an advisory Lock (advisory Lock). The so-called forced lock, better understanding, is the door of your home that lock, the most deadly is only a key, only one process can operate. The so-called advisory lock, the essence is a protocol, you access the file before, check the lock, this time the lock is its role, if you are not so kind, regardless of 3,721, must read and write, then advise the lock does not have any effect. And to abide by the protocol, read and write the lock before the process, called the cooperation process.
plus , flock can have shared lock and exclusive lock, LOCKF only support exclusive lock, but fcntl inside parameters flock can have rdlck read lock.
again , the difference between flock and FCNTL/LOCKF is mainly the difference between fork and DUP, and there is talk behind it.
In addition , flock can no longer be used on NFS file systems, if you want to use file Locks on NFS, use FCNTL.
Then, after a bunch of fork and DUP, the performance of Flock was followed. can go to see the original text.
2. LOCKF and Fcntl
L Function prototypes
#include <unistd.h>
int lockf (int fd, int cmd, off_t len);
FD is the open file descriptor returned by open.
The value of CMD is:
F_lock: File Mutex lock, if the file is locked, it will be blocked until the lock is released.
F_tlock: Same as F_lock, but if the file has been locked, it will not block, and return an error.
F_ulock: Unlock.
F_test: If the test file is locked, return 0 if the file is not locked, or 1.
Len: The length to lock from the beginning of the current position of the file.
With function parameters, you can see that LOCKF only supports exclusive locks and does not support shared locks.
#include <unistd.h>
#include <fcntl.h>
int fcntl (int fd, int cmd, .../* arg */); ( usage:int ret = fcntl(fd, F_SETLKW, &lock); )
in fact, lock is the following data structure :
struct Flock {
...
Short l_type;/* type of Lock:f_rdlck, F_wrlck, F_unlck */
Short l_whence; /* How to interpret L_start:seek_set, seek_cur, Seek_end */
off_t L_start; /* Starting offset for lock */
off_t L_len; /* Number of bytes to lock */
pid_t L_pid; /* PID of process blocking our lock (F_GETLK only) */
...
};
File record lock-related cmd divided into three kinds:
F_SETLK: Request a lock (read lock F_rdlck, write lock F_wrlck) or Release (F_UNLCK), but if kernel cannot grant the lock to this process (the other process has robbed the first, took the lock), not silly, etc., return error.
F_SETLKW: And F_setlk almost the same, the only difference, this fellow is a dead-minded Zhu Er, application is not, silly wait.
F_GETLK: This interface is information about acquiring locks: This interface modifies our incoming struct flock.
The function parameter function can be seen FCNTL is the most powerful, it supports both shared and exclusive locks, that is, can lock the entire file, but also can lock only a portion of the file.
Here's a look at FCNTL/LOCKF features:
1. Recursive ( same flock)
2. The read lock (shared lock) file must be read open, and the write lock (exclusive lock) file must be write-open.
3. The process cannot use the F_GETLK command to test whether it itself holds a lock on a part of the file.
4. When the process terminates, all file locks that he creates are released ( same as Flock).
5. At any time when a descriptor is closed, any lock on the file that the process can refer to by this descriptor is freed (the locks are set by the process), which is different from flock .
FD1 == = = Open (pathname, ...); Close (FD2);
6. The child process generated by the fork does not inherit the lock set by the parent process, which is also different from flock . ( because the lock created by flock is associated with the File open table entry (struct file) , not the FD, the FD can manipulate the lock, so the child process inherits the lock of the parent process .) Flock inside to close all the copied FD, the lock will be released)
7. After exec executes, the new program can inherit the lock of the original program, which is the same as Flock . (If Close-on-exec is set for FD, the FD is closed before exec and the lock for the corresponding file is freed).
8. Support Mandatory lock ( different from flock ). Here's what it says.
3. Relationship of two kinds of locks
So what does flock have to do with the lock on Lockf/fcntl? The answer is not affected. The test procedure is as follows:
#
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
int main(int argc, char **argv)
{
int fd, ret;
int pid;
fd = open("./tmp.txt", O_RDWR);
ret = flock(fd, LOCK_EX);
printf("flock return ret : %d\n", ret);
ret = lockf(fd, F_LOCK, 0);
printf("lockf return ret: %d\n", ret);
sleep(100);
return 0;
}
The test results are as follows:
$./a.out
Flock return ret:0
LOCKF return ret:0
visible flock Lock, does not affect the LOCKF locking . Two outside we can get the state of the lock through the/proc/locks view process.
$ps aux | grep a.out | Grep-v grep
123751 18849 0.0 0.0 11904 to PTS/5 s+ 01:09 0:00./a.out
$sudo Cat/proc/locks | grep 18849
1:posix advisory WRITE 18849 08:02:852674 0 EOF
2:flock advisory WRITE 18849 08:02:852674 0 EOF
We can see the information on the lock below the/proc/locks : I will now describe the meaning:
1) POSIX FLOCK This is a more explicit, which type of lock. The flock system call produces a flock,fcntl call f_setlk,f_setlkw or LOCKF produces a POSIX type , which shows that the types of locks produced by the two invocations are different;
2) advisory indicates is to advise the lock;
3) write as the name implies, is written lock, and read lock;
4) 18849 is the process ID that holds the lock. Of course, for flock this type of lock, there is a situation where the process has exited.
5) 08:02:852674 indicates that the corresponding disk file is located on the device's main device, the secondary device number, and the file corresponding inode numbers.
6) 0 represents the location of the place
7) EOF represents the end position. These two fields are useful for fcntl types, which are always 0 and EOF for flock.
FCNTL supports a mandatory lock: Opens its set group ID bit (S_ISGID) to a specific file and turns off its group execution bit (S_IXGRP), which opens a mandatory locking mechanism for the file. If you want to use mandatory locks in Linux, use-omand to open this mechanism when the file system is mount.
See this post:
http://blog.jobbole.com/16882/
With Fcntl locking:
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char **argv) {
if (argc > 1) {
int fd = open(argv[1], O_WRONLY);
if(fd == -1) {
printf("Unable to open the file\n");
exit(1);
}
static struct flock lock;
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
lock.l_pid = getpid();
int ret = fcntl(fd, F_SETLKW, &lock);
printf("Return value of fcntl:%d\n",ret);
if(ret==0) {
while (1) {
scanf("%c", NULL);
}
}
}
}
Use the Mount command to re-mount the root file system with the "Mand" parameter, as shown below. This enables the lock feature to be enforced at the file system level. Note: You must switch to the root user to execute the following command.
# Mount-oremount,mand/
Create two files named "Advisory.txt" and "Mandatory.txt" in the executable (file_lock) directory. For "Mandatory.txt" Enable Set-group-id, and do not enable Group-execute-bit, as follows:
# touch advisory.txt
# touch mandatory.txt
# chmod g+s,g-x mandatory.txt
Test the Collaboration Lock:
Execute the sample program with "advisory.txt" as a parameter.
# ./file_lock advisory.txt
This program will wait for user input.
From another terminal or console, try entering the following command line (enter without checking for locks):
# ls >> advisory.txt
In the above example, the ls command will write its output to the advisory.txt file. Even if we acquire a write lock, some processes (non-cooperative) can still write data to the file. This is called a "cooperative" lock.
To test a forced lock:
Execute the sample program again with "mandatory.txt" as a parameter.
# ./file_lock mandatory.txt
From another terminal or console, try entering the following command line:
# ls >> mandatory.txt
In the above example, the ls command waits for the file lock to be removed before writing its output to the mandatory.txt file. Although it is still a non-cooperative process, mandatory locking works.
Finish
Linux file Lock Learning-flock, LOCKF, Fcntl