Small Talk about Linux: file locks and their instances

Source: Internet
Author: User
Tags flock function prototype

1. Basic concept of File lock

Linux software, hardware resources are files (all files), files in multi-user environment is shareable.

File locks are a mechanism used to solve shared use of resources: When multiple users need to share a file, Linux typically uses a method of locking the file to avoid a competing state of shared resources .

File locks include a recommended lock and a mandatory lock:

recommended Lock: requires every process that uses a locked file to check for locks and to respect existing locks. In general, the kernel and the system do not use the proposed lock, they rely on the programmer to comply with this rule.
Mandatory Lock: is a lock executed by the kernel, and when a file is locked for write operations, the kernel blocks any other files from reading and writing. The effect of using a mandatory lock on performance is significant, and each read and write operation must check for a lock existence.


In Linux, the functions that implement file locking are LOCKF () and Fcntl ()

    • LOCKF () to apply a proposed lock to a file

    • Fcntl () can not only apply the proposed lock, but also strengthen the locking system.

    • Fcntl () can also lock a record in a file, which is a record lock.

    • Record locks can also be divided into read and write locks, where read locks, also known as shared locks, enable multiple processes to establish a read lock in the same part of the file.

    • Write locks, also known as repel locks, can have only one process at a time to establish a write lock on a part of a file.

    • Read locks and writes cannot be established at the same time in the same part of the file.

2. Fcntl () function format
Fcntl is a very versatile function that can perform various operations on open files, including managing file locks, getting and setting file descriptor flags, getting and setting file status flags, copying file descriptors, and more.
Required header File
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
Function prototype: int fcntl (int fd,int cmd,...);
int fcntl (int fd,int cmd,long arg);
int fcntl (int fd, int cmd, struct flock *lock)
Function pass-in value FD: File descriptor manipulated by parameter cmd


Function prototypes
int fcntl (int fd,int cmd,long arg);
int fcnt1 (int fd, int cmd, struct flock *lock)
function passed in value cmd
F_DUPFD: Copying an existing descriptor
F_GETFD: Get FD's close-on-exec (off on execution) file descriptor flag, if the flag is not set, then the file will remain open after the exec () function
F_SETFD: Sets the CLOSE-ON-EXEC flag, which is determined by the fd_cloexec bit of the parameter arg
F_GETFL: Get the Open setting flag
F_SETFL: Changing the Open settings flag
F_GETLK: Determines whether a file lock can be made according to the lock parameter value
F_SETLK: Set the lock parameter value of the file lock


About Close_on_exec
Close_on_exec is a bitmap flag for all file descriptors (file handles) of a process, each of which represents an open file descriptor that determines the file handle that needs to be closed when calling system call Execve () (see INCLUDE/FCNTL.H). When a program uses the fork () function to create a child process, it typically calls the Execve () function in that child process to load the execution of another new program. At this point the child process is completely replaced by the new program and the new program is started in the child process. If a file descriptor is set in the corresponding bit in the close_on_exec, the descriptor will be closed when the EXECVE () is executed, otherwise the descriptor will always be open.

function passed in value cmd
F_SETLKW: This is the blocking version of F_setlk (w in the command name indicates wait). When it cannot be locked, it goes to sleep, and if it can be locked or the signal is snapped back
Lock: is a pointer to the flock structure that sets the specific state of the record lock
function return value
On success, the return value depends on the second parameter of CMD
-1: Error





CMD value mode
F_GETLK, f_setlk or f_setlkw: Gets/sets the function of record lock, succeeds returns 0, returns 1 if there is an error, and the reason for error is stored in errno.
F_getlk : Tests whether the lock described by lock can be used. If there is a lock that prevents the creation of the lock described by lock, the information for the existing lock is written to the structure that the lock points to (the type of l_type-already locked, the l_pid-process number that is locked). If this is not the case, other information in the structure pointed to by lock remains the same except that L_type is set to F_unlck.

F_SETLK: Sets or clears the lock of a file according to the information about the lock that the third parameter lock points to the flock structure.


F_SETLK: used to implement shared (or read) locks (F_RDLCK) or exclusive (write) locks (f_wrlck), you can also remove both locks (f_unlck). If a shared or exclusive lock cannot be set, Fcntl () will return immediately eagain


3. FCNTL () Usage Example

In the following example, the corresponding field of the flock struct is assigned the appropriate value first.
Then use two times the Fcntl () function, respectively, to determine whether the file can be locked and related files locked, the cmd value used here is f_getlk and f_setlk (or f_setlkw).
Use the F_GETLK command to determine whether the lock operation described by the flock structure can be performed:
If you can lock, then the flock structure of the l_type will be set to F_unlck, the other domain is unchanged;
Otherwise, L_pid is set to the process number that owns the file lock, L_type is set to the type of the lock, and the other fields do not change.


    • The file record function source code is as follows (the file is saved as MYLOCK.C):

/* file saved as mylock.c */int lock_set (int fd,int type) {struct flock old_lock,lock;lock.l_whence = Seek_set;lock.l_start = 0;loc K.l_len = 0;lock.l_type = Type;lock.l_pid = -1;fcntl (Fd,f_getlk,&lock); if (lock.l_type! = F_unlck) {if (Lock.l_type = = F_rdlck)  {printf ("Read lock already set by%d\n", Lock.l_pid);} else if (Lock.l_type = = F_wrlck) {printf ("Write lock already set by%d\n", Lock.l_pid);}} Lock.l_type = Type;if ((fcntl (fd,f_setlkw,&lock)) < 0) {printf ("Lock Failed:type =%d\n", lock.l_type); return 1;} Switch (lock.l_type) {case f_rdlck:{printf ("Read Lock set by%d\n", Getpid ());} Break;case f_wrlck:{printf ("Write lock set by%d\n", Getpid ());} Break;case f_unlck:{printf ("Release Lock by%d\n", Getpid ()); return 1;} Break;default:break;} return 0;}

    • The following instance is a test case for a file write lock, with the file name WIRTE_LOCK.C.
      This first creates a hello file, then writes a lock on it, and finally releases the write lock, as shown in the following code:

#include <stdio.h> #include <unistd.h> #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #include <stdlib.h> #include "mylock.c" int main (void) {  int fd;/* first Open File */FD = open ("Hello" , O_RDWR | O_creat, 0644); if (FD < 0) {   printf ("Open file error\n"); exit (1);     }     Lock_set (FD, f_wrlck);  /* Write lock on File *  /GetChar ();             /* Program paused, press ENTER to continue *     /Lock_set (FD, F_UNLCK);/* Unlock file *   /GetChar ();   Close (FD);   Exit (0);    return 0;}


Run as follows:



Test on PC:
Open two terminals and run the program at the same time on two terminals to achieve the effect of multiple process operations on one file.
First run in Terminal 1, then run on Terminal 2, notice the first line of Terminal two output.




This shows that the write lock is a mutex and only one write lock exists at a time.


The next program is the test case for the file read lock, the same principle as the program above. The file name is READ_LOCK.C.

#include <unistd.h> #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h># Include <stdio.h> #include <stdlib.h> #include "mylock.c" int main (void) {int fd;fd = open ("Hello", O_RDWR | O_creat, 0644); if (FD < 0) {printf ("Open file error\n"); exit (1);  } Lock_set (FD, F_RDLCK);/* read lock */getchar () on file, Lock_set (FD, F_UNLCK);/* Unlocks file */getchar (); close (FD); exit (0);    return 0;}

The results of the operation are as follows:



Also open two terminals, and first start the program on Terminal One, the results of the operation are as follows:


It is observed that the read lock is a shared lock.

Small Talk about Linux: file locks and their instances

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.