First flock and Fcntl are system calls, and LOCKF are library functions. LOCKF is actually a fcntl package, so the LOCKF and Fcntl are the same, and the effect of locking the file is the same. The Fcntl and LOCKF are put together in most cases when the analysis is different. The next step is to look at the use of each function, from the way it is used and the effect of each function to see the difference.
1. Flock
Function prototypes
int flock (int fd, int operation); Apply or remove a advisory lock on the ' open file specified by FD, just a recommended lock
Where FD is the file descriptor returned by system call Open, theoperation options are:
1.lock_sh: shared locks
2.LOCK_EX: exclusive lock or exclusive lock
3.lock_un: unlock.
4.lock_nb: non-blocking (used with all three of these operations)
As for the Flock function, it is important to know that the flock function can only lock the entire file, but not the part of the file, which is the first significant difference in FCNTL/LOCKF, which can lock an area of the file. Second, flock can only produce advisory locks. We know that Linux exists a forced lock (mandatory lock) and advises the lock (advisory lock). The so-called forced lock, better understanding, is that the lock on your door, the most deadly is only a key, only one process can operate. The so-called advise lock, the essence is a kind of agreement, you access the file before, check the lock first, this time lock only its function, if you are not so kind, regardless of 3,721, must read and write, then advise lock has no effect. The process of checking the locks before reading and writing is called the cooperative process. Again, the difference between flock and FCNTL/LOCKF is mainly in fork and DUP.
(1) The lock created by flock is associated with the File open table entry (struct file), not FD. This means that after copying the file fd (via fork or DUP), the lock can be manipulated through the two FD (for example, through a FD lock, and the lock can be released through another FD), which means that the child process inherits the lock of the parent process. But when one of the FD is closed during locking, the lock is not released (because the file structure is not released) and the lock is released only if all the replicated FD is closed. Test program into program one.
Program One
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h >
int main (int argc, char * * argv)
{
int ret;
int fd1 = open ("./tmp.txt", O_RDWR);
int fd2 = DUP (FD1);
printf ("Fd1:%d, fd2:%dn", FD1, FD2);
ret = Flock (FD1,LOCK_EX);
printf ("Get Lock1, ret:%dn", ret);
ret = Flock (FD2,LOCK_EX);
printf ("Get Lock2, ret:%dn", ret);
return 0;
The results of the operation, as shown in the FD1 lock, do not affect the program through the FD2 lock. For a parent-child process, refer to program two.
Program Two
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h >
int main (int argc, char * * argv)
{
int ret;
int pid;
int fd = open ("./tmp.txt", O_RDWR);
if ((PID = fork ()) = = 0) {
ret = flock (FD,LOCK_EX);
printf ("Chile Get lock, FD:%d, ret:%dn", FD, ret);
Sleep (a);
printf ("Chile exitn");
Exit (0);
}
ret = Flock (FD,LOCK_EX);
printf ("Parent Get lock, FD:%d, ret:%dn", FD, ret);
printf ("Parent exitn");
return 0;
}
As shown in the diagram, the child process holds the lock and does not affect the parent process acquiring the lock through the same FD or vice versa.
(2) Open the same file two times, the resulting two FD is independent (because the bottom corresponds to two file objects), through one of the lock, through the other unlocked, and can not be unlocked before the first unlocked. Test program such as program three:
Cheng
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/file.h >
int main (int argc, char * * argv)
{
int ret;
int fd1 = open ("./tmp.txt", O_RDWR);
int fd2 = open ("./tmp.txt", O_RDWR);
printf ("Fd1:%d, fd2:%dn", FD1, FD2);
ret = Flock (FD1,LOCK_EX);
printf ("Get Lock1, ret:%dn", ret);
ret = Flock (FD2,LOCK_EX);
printf ("Get Lock2, ret:%dn", ret);
return 0;
}
As a result, the lock can no longer be acquired through the FD1 after acquiring it through the FD2.
(3) The state of the file lock is unchanged after using exec.
(4) Flock can no longer be used on NFS file systems, use FCNTL if you want to use file Locks in NFS.
(5) Flock lock can be recursive, that is, through the DUP or fork generated by the two FD, can be added lock without creating deadlock.
2. LOCKF and Fcntl
Function prototypes
#include
int lockf(int fd, int cmd, off_t len);
FD is the open file descriptor returned through open.
The value of CMD is:
F_lock: The file is mutually exclusive lock, if the file is locked, it will block until the lock is released.
F_tlock: Same as F_lock, but if the file has been locked, will not block, and return error.
F_ulock: Unlock.
F_test: Test file is locked, if the file is not locked then return 0, otherwise return-1.
Len: The length to be locked from the beginning of the file's current position.
By using function parameters, you can see that LOCKF only supports exclusive locks and does not support shared locks.
#include
#include
int fcntl (int fd, int cmd, .../* arg/*);
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 is divided into three kinds:
F_SETLK: Apply for Lock (read lock F_rdlck, write lock F_wrlck) or Release (F_UNLCK), but if kernel cannot grant the lock to this process (which was grabbed by other processes first, takes up the lock), not silly, etc., return error.
F_SETLKW: And F_setlk almost the same, the only difference, this fellow is a dead heart of the advocate, the application is not, just silly.
F_GETLK: This interface is information about getting locks: This interface modifies our incoming struct flock.
The function parameter function can be seen that FCNTL is the most powerful, it supports both shared and exclusive locks, that is, can lock the entire file, but only a part of the file lock.
Here's a look at the FCNTL/LOCKF features:
(1) The lock is recursive, if a process has a lock on a file range, then the process attempts to add a lock in the same interval, the new locks will replace the old lock.
(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. The F_GETLK command defines a description that returns information indicating whether an existing lock prevents the calling process from setting its own lock. Because the f_setlk and F_SETLKW commands always replace the existing locks of the process, the calling process will never block any locks that are held by itself, so the F_GETLK command will never report the lock that the calling process itself holds.
(4) When the process terminates, all of the file locks that he creates are released, and so does the Doctor flock.
(5) When a descriptor is closed at any time, the process is freed from any lock on a file that can be referenced by this descriptor (which is set by the process), unlike flock. Such as:
FD1 = open (pathname, ...);
LOCKF (FD1, F_lock, 0);
FD2 = DUP (FD1);
Close (FD2);
Then, after close (FD2), the lock that is set on the FD1 is freed, and if the DUP is replaced with open to open the same file on the other descriptor, the effect is the same.
FD1 = open (pathname, ...);
LOCKF (FD1, F_lock, 0);
FD2 = open (pathname, ...);
Close (FD2);
(6) The child process produced by fork does not inherit the lock set by the parent process, and this differs from the flock.
(7) After exec, the new program can inherit the original program lock, this and flock is the same. (If Close-on-exec is set on FD, then the FD will be turned off before exec, and the lock of the corresponding file will be released).
(8) Support for mandatory locks: Open the setting group ID bit (S_ISGID) for a particular file and close its group execution bit (S_IXGRP), and the file is opened with a mandatory lock mechanism. If you want to use a mandatory lock in Linux, use _omand to open the mechanism when the file system is mount.
3. Relationship of two kinds of locks
So what does flock have to do with the locks 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:%dn", ret);
ret = LOCKF (FD, F_lock, 0);
printf ("LOCKF return ret:%dn", ret);
Sleep (m);
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 of the lock. In addition we can /proc/locks
get the status of the lock by looking at the process.
$ps aux | grep a.out | Grep-v grep
123751 18849 0.0 0.0 11904 440 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 lock under the/proc/locks: I now describe the meaning separately:
1 POSIX FLOCK This is more explicit, which is the type of lock. The flock system call produces the FLOCK,FCNTL call f_setlk,f_setlkw or the LOCKF produces a POSIX type, and there are times when the types of locks produced by the two calls are different;
2) Advisory indicated is the advising lock;
3 Write as the name implies, is written lock, there is read lock;
4) 18849 is the process ID holding the lock. Of course, for flock this type of lock, a process has already exited the situation.
5) 08:02:852674 The corresponding disk files of the device's main equipment, the secondary device number, as well as the file corresponding inode numbers.
6) 0 indicates the position of the place
7) EOF indicates the end position. These two fields are useful for fcntl types, and for flock to be always 0 and EOF.
The above is Linux fcntl (), LOCKF and flock the whole content of the difference, I hope this article is helpful to everyone.