Linux Program Design-File Lock (seventh chapter)

Source: Internet
Author: User
Tags flock fread function prototype semaphore

7.2 File Lock This is a file lock for Linux and the code is downloaded in the file lock code. File locking is a very important part of a multi-user, multitasking operating system. programs often need to share data, which is usually done through a file. Therefore, it is very important for these programs to establish some kind of control file. Only then can the file be updated in a safe way, or, when a program is writing to a file, the file will enter a temporary state, in which case the other program will automatically stop waiting for the end of the state if it tries to read the file.
Linux offers a variety of features for file locking, the simplest of which is Create a lock file as an atomic operationCalled atomic manipulation is when you create a lock file, the system will not allow any other things to happen. This is gives the program a way to ensure that the file it creates is unique, and that the file cannot be created at the same time by another program
The second way is more advanced, it allows program locks A portion of the file so that you can access this part of the content alone。 There are two different ways to implement a second form of file locking. We'll just go into one of these in detail, because the two are very similar--the second way is just a little different from the program interface.
7.2.1 Creating a lock file Many applications only need to be able to create a lock file for a resource. Other programs can then check the file to see if they are allowed to access the resource.
These lock files are usually placed in a specific location with a file name associated with the resource being controlled. For example, when a modem is being used, Linux typically creates a lock file in the/var/spool directory.
Note that lock files are just roles that act as an indicator, and programs need to work together to use them. The lock file is only a recommended lock, not a forced lock.
In order to Create a file for the lock indicator that can use the open system call defined in the Fcntl.h header file with the O_creat and O_EXCL flags。 This allows you to operate at the same time as an atom do two work: Make sure the file does not exist, and then create it.
Writing a program lock1.c
This program calls open with the o_creat and O_EXCL flags to create the file/tmp/lck.test. The first time you run the program, the open call succeeds because the file does not exist. However, subsequent calls to the program failed because the file already exists. If you want the program to execute successfully again, you must delete the lock file.
At least in the Linux system, error number 17 represents eexist, which is used to indicate that a file already exists. The error number is defined in the header file errno.h or in the header file it contains.
In this case, the error number is actually defined in the header file/usr/include/asm-generic/errno-base.h:
#define Eexist/*file exitsts*/
This is a fit with the expression open (O_create | O_EXCL) failed error number.
If a program executes, it only needs to monopolize a resource for a short period of time-the critical section-it will need to create the lock file using the open system call before entering the critical section, and then delete the lock file with the unlink system call when exiting the critical section.
Writing a program lock2.c
./lock2.exe &./lock2.exe
This command runs two copies of the program, runs a copy of Lock2 in the background, and runs another copy in the foreground.
This program uses the while statement to loop the program 10 times and then accesses the critical resource by creating a unique lock file,/tmp/lck.test2. If the file fails because it already exists, the program waits for a short period of time to try again. If it succeeds, it can access the resource. In the section labeled "Critical section", you can perform any processing that requires exclusive access.
After the program has used the resource, the lock is released by deleting the lock file, and then some other processing (such as sleep (2)) can be performed before the lock is re-requested. Here the lock file plays a role similar to binary semaphore, and the question "Can I use this resource?" "Give each program a" yes "or" no "answer, and chapter 14 further learns the semaphore.
This is an arrangement of inter-process coordination, and it is important to realize that the code must be properly written to make it work properly. When a program creates a lock file that fails, it cannot resolve the issue by deleting the file and re-trying the method. This may allow it to create a lock file, but another program that creates the lock file will not know that it no longer has exclusive access to the resource.
7.2.2 Zone locking is a good choice for creating locks to control exclusive access to resources such as serial ports or infrequently accessed files, but it is not suitable for accessing large shared files. Suppose you have a large file that is written by a program, but it is updated by many different programs at the same time. This can happen when a program is responsible for documenting data that has been collected for a long time, while other programs are responsible for processing the recorded data. Handlers cannot wait for the logger to end because the logger will be running all the time, so they need some coordination methods to provide concurrent access to the same file.
This problem can be resolved by locking the file area, where a specific part of the file is locked, but other programs can also access other parts of the file, which are either locked in a file segment or locked in a file area. Linux provides at least two ways to achieve this: using FCNTL system calls and using LOCKF calls. We will mainly introduce the Fcntl interface, as it is the most commonly used interface. LOCKF and Fcntl are very similar, and in Linux it is generally used as an alternative interface for FCNTL. However, the locking mechanisms of fcntl and LOCKF do not work at the same time: they use different underlying implementations, so it is absolutely not possible to mix these two types of calls, but to stick with one of them.
In chapter three, the definition of fcntl invocation is as follows:
#include <fcntl.h>
int fcntl (int filds, int command, ...);
FCNTL operates on an open file descriptor and can accomplish different tasks based on the command parameter settings. It provides 3 command options for file locking:
F_getlk
F_setlk
F_setlkw
When using these command options, the third argument of fcntl must be a pointer to the flock structure, so the actual function prototype is:
int fcntl (int fildes, int command, struct flock* flock_structure);
The flock (file lock) structure relies on a specific implementation, but it contains at least the following members:
Short L_type
Short L_whence
off_t L_start
off_t L_len
pid_t L_pid
Value of the L_type member
defined in the header file fcntl.h
Value Description
F_rdlck shared (or read) lock, many different processes can have shared locks on the file consent area. As long as any process has a shared lock, no process can acquire an exclusive lock on that zone. In order to obtain a shared lock, the file must be opened in "read" or "read/write" mode.
F_unlck Unlock, used to clear the lock
F_wrlck Exclusive (or write) lock。 Only one process can have an exclusive lock in any particular area of the file. Once a process has a write lock, other processes cannot acquire any type of lock in the zone. In order to obtain an exclusive lock, the file must be opened in "write" or "read/write" mode.
l_whence, L_start, and L_len members define an area in the file, a contiguous set of bytes。 The value of l_whence must be one of Seek_set, Seek_cur, and Seek_end. They correspond to the header, the current position, and the end of the file, respectively. L_whence defines the relative offset value of L_start, where L_start is the first byte of the range. L_whence is usually set to Seek_set, at which point the L_start is calculated from the beginning of the file. The L_len parameter defines the number of bytes in the range.
The L_pid parameter is used to record the process holding the lock.
Each byte in a file can have only one type of lock at any one time: a shared lock, an exclusive lock, or a unlock. There are very many combinations of commands and options available for FCNTL calls.
1.F_GETLK command
The first command is f_getlk, it is used to get lock information for a fildes open file。 It does not attempt to lock the file. The calling process passes the lock type information that you want to create to Fcntl, and fcntl with the F_GETLK command returns any information that will block the acquisition of the lock.
The values used in the flock structure are as follows:
Value Description
L_type The value is F_rdlck if it is a shared (read-only) lock, or f_wrlck if it is an exclusive (write) lock
One of the L_whence Seek_set, Seek_cur, Seek_end
The relative position of the first byte of the L_start file area
L_len number of bytes in the file area
L_pid The identifier of the process holding the lock
A process might use the F_GETLK to view the current lock state of a region in a file, and it should set the flock structure to indicate the type of lock it requires and define the area of the file it is interested in. The FCNTL call returns a value other than-1 if successful. If the file is locked to prevent the lock request from executing successfully, FCNTL overwrites the flock structure with relevant information. If the lock request can be executed successfully, the flock structure will remain intact. If the F_GETLK call fails to get information, it returns 1 indicating failure.
If the F_GETLK call succeeds, the calling program must examine the contents of the flock structure to determine if it has been modified. Because the value of L_pid is set to the identifier of the process holding the lock, it is convenient to check the field to see if the flock structure has been modified.
2. f_setlk Command
This command attempts to lock or unlock an area of a file that Fildes points to。 The values used in the flock structure are as follows:
Value Description
L_type if it is a shared (read) lock, the value is F_rdlck, if the exclusive (write) lock is f_wrlck, and if it is unlocked f_unlck
L_pid not used
The area to be locked is defined by the values of L_start, L_whence, and l_len in the flock structure. If the lock succeeds, FCNTL returns a value other than-1, or 1 if it fails.
3.F_SETLKW command
The F_SETLKW is the same as the f_setlk command, but when the lock cannot be acquired, the call waits until it can. Once the call begins to wait, it returns only if the lock can be acquired or a signal is received.
All locks that a program has on a file are automatically purged when the corresponding file descriptor is closed. Locks are also automatically cleared at the end of the program.
7.2.3 the Read and write operation in the locked state when After you lock the file area, you must use the underlying read and write calls to access the data in the file instead of using the more advanced fread and Fwrite call, because Fread and fwrite cache data that is read and write, so performing a fread callback to read the first 100 bytes in a file might read more than 100 bytes of data and cache the extra data in the library. If the program uses fread again to read the 100-byte data, it will actually read the data that has been cached in the library, without triggering an underlying read to fetch more data from the file.
Writing a program lock3.c
The program first creates a file, opens it in a readable and writable manner, and then adds some data to the file. Then set two zones in the file: The first zone is 10~30 bytes, the shared lock is used, the second area is 40~50 bytes, and an exclusive lock is used. The program then calls Fcntl to lock the two areas and waits 10 seconds before closing the file and exiting the program.
Writing a program lock4.c
To test the lock, you need to run the program Lock3.exe first, and then run the program Lock4.exe to test the lock.
./lock3.exe &./lock4.exe
The value of L_type in the program corresponds to a value of 1 that is defined as f_wrlk,l_type and the corresponding definition is f_rdlk. So a value of L_type of 1 indicates that the lock failed because a write lock already exists, and the value of L_type is 0 because a read lock already exists. Either a shared or exclusive lock will succeed on an area that is not locked by the LOCK3 program in the file.
You can see that a shared lock can be set on the 10~30 byte because the program LOCK3 set a shared lock on that zone instead of an exclusive lock. On 40~50 bytes, both locks fail because Lock3 already has an exclusive lock (F_WRLCK) set on the zone.
7.2.4 file Lock competition next test two programs for the folder on the same area of the lock when the situation occurs. Use Lock3.exe again to lock the file, and then use a new program Lock5.exe to try to lock it.
The role of Lock5.exe is no longer the lock state of the different parts of the test file, but instead attempts to lock the area that is already locked in the file.
By the way, the third chapter is about the FCNTL system call, FCNTL system calls to the underlying file descriptor provides a lot of ways to do.
#include <fcntl.h>
int fcntl (int fields, int cmd);
int fcntl (int fileds, int cmd, long arg);
With FCNTL system calls, you can perform various actions on open file descriptors, including copying them, getting and setting file descriptor flags, getting and setting file status flags, and managing recommended file locks.
7.2.5 Other lock commands There is another way to lock a file; the LOCKF function, which is also manipulated by a file descriptor. The prototype is:
#include <unistd.h>
int lockf (int fildes, int function, off_t size_to_lock);
The value of the function parameter is as follows:
F_ulock: Unlocking
F_lock: Setting an exclusive lock
F_tlock: Test and set an exclusive lock
F_test: Testing locks set by other processes
The Size_to_lock parameter is the number of bytes of the operation, which is calculated from the current offset value of the file.
LOCKF has a simpler interface than the FCNTL function, mainly because it is less functional and flexible than the FCNTL function. To use this function, you must first search for the starting position of the area you want to lock, and then call it as a parameter to the number of bytes to lock.
As with the Fcntl method for file locking, all locks set by LOCKF are recommended locks, and they do not really block the data in the read-write file. The detection of locks is the responsibility of the program.
7.2.6 deadlocks assume that all two programs update the same file, and they need to update bytes 1 and 2 in the file at the same time. Program a chooses to update byte 1 first, then update Byte 2, and program B chooses to update byte 2 first and then update Byte 1.
Both programs start at the same time, program a locks byte 1, program B locks byte 2, and a tries byte 2 unsuccessfully, so a needs to wait, and B also needs to wait.
These two programs are not able to continue the execution of the situation, is called a deadlock (Deadlok or deadly embrace). This problem is common in database applications where deadlocks can occur easily when many users access the same data frequently. Most business relational databases are capable of detecting deadlocks and unlocking them automatically, but the Linux kernel does not, which requires some external interference, such as forcing one of the programs to be terminated to solve the problem.

Linux Programming-file lock (seventh)

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.