File locks are often used in two areas:
1. One is to lock the critical data in the file, such as the number of votes in the file when concurrent voting 2. The second is to implement concurrency control of the process by using a write lock with mutually exclusive nature.
/* Use file lock */<f5>
#include <fcntl.h>
Fcntl (int fildes,int cmd,struct flock* arg);
Cmd:f_getlk,f_setlk,f_setlkw
Gets or sets the record lock.
If an error occurs, all commands are returned-1.
The structure of lock information in fcntl.h
struct flock
{
/* Lock Type */
Short l_type;//value is read lock F_rdlck, write lock F_wrlck, release lock F_unlck
/* Start position of lock area */
Short l_whence;//the relative position of the start address of the lock area, with a value of seek_set,seek_cur,seek_end
Long l_start;//The offset of the start address of the lock area, together with the l_whence to determine the absolute starting position of the lock area
/* Length of lock area */
Long l_len;//if 0, the lock to the end of the file
/* ID number of the process that owns the lock */
Short L_pid;
}
F_GETLK: Look for lock information before applying for file lock.
When multiple file locks exist in the development area, FCNTL only returns one.
The call returns any non-negative integer successfully, otherwise returns-1
The type of lock the user submits the request for, and the function returns the lock information that is incompatible with the lock type.
If a read lock is committed, the FCNTL only returns a write lock within the zone and ignores read and write. Because read locks are not compatible with write locks only
If a write lock is committed, FCNTL only returns all lock information within the zone. Because the write lock is incompatible with any other lock
If there is no file lock in the zone, the member l_type of the flock structure that arg points to will be set to F_unlck.
So use a write lock to test whether an existing lock is already in an area of the file.
F_SETLK: Set read lock, write lock, clear lock.
The call failed to return 1, otherwise the other value is returned.
If the process has applied for a lock in the region, the new lock replaces the old lock in that area
If the zone has been locked by another process and is incompatible with the new lock, the function will fail to invoke.
F_SETLKW:
For F_SETLK blocking version, set read lock, write lock, clear lock, but this blocking version will cause the process to block until the request is completed. F_SETLK will return immediately if execution fails.
Use flow: Will test lock, request lock, Release lock three block package into three function calls, encapsulation as library function will make later use simple and convenient many.
Test Lock: Query the file descriptor corresponding to the file lock information, determine whether there is incompatible with the stored lock
1. Encapsulation Test lock function: void seeklock (int fd,int start,int len);
Function: Determine the file descriptor corresponding to the file from the beginning of the file offset from start at the beginning of the Len Byte area of the lock information:
void Seeklock (int fd,int start,int len)
{
struct flock arg;
Arg.l_type = F_wrlck;
Arg.l_whence = Seek_set;
Arg.l_start = start;
Arg.l_len = Len;
if (fcntl (fd,f_getlk,&arg) = =-1)
{
fprintf (stderr, "see Lock failed.\n");
}
else if (Arg.l_type = = F_unlck)
{
fprintf (stderr, "No lock from%d to%d\n", Start,len);
}
else if (Arg.l_type = = F_wrlck)
{
fprintf (stderr, "Write Lock from%d to%d,id =%d\n", start,len,arg.l_pid);
}
else if (Arg.l_type = = F_rdlck)
{
fprintf (stderr, "Read Lock from%d to%d,id =%d\n", start,len,arg.l_pid);
}
}
2. Package Request read Lock function
void Getreadlock (int fd,int start,int len);
Blocked mode requests a shared read lock in a file that corresponds to a file descriptor, and the locked area is an area of Len byte length that starts at the offset start.
void Getreadlock (int fd,int start,int len)
{
struct flock arg;
Arg.l_type = F_rdlck;
Arg.l_whence = Seek_set;
Arg.l_start = start;
Arg.l_len = Len;
if (fcntl (fd,f_setlkw,&arg) = =-1)
{
fprintf (stderr, "[%d] Set Read Lock failed.\n", Getpid ());
}
Else
fprintf (stderr, "[%d] Set Read Lock from%d to%d\n", Getpid (), Start,len);
}
3. Package request Set Write lock function
The mutex write lock application function Getwritelock, the prototype is:
void Getwritelock (int fd,int start,int len)
Features: Blocked mode requests a mutex write lock in the file descriptor file, and the locked area is the length of Len bytes that starts at the offset start.
void Getwritelock (int fd,int start,int len)
{
struct flock arg;
Arg.l_type = F_wrlck;
Arg.l_whence = Seek_set;
Arg.l_start = start;
Arg.l_len = Len;
if (fcntl (fd,f_setlkw,&arg) = =-1)
{
fprintf (Srderr, "[%d] Set Write Lock failed.\n", Getpid ());
}
Else
fprintf (stderr, "[%d] Set Write Lock%d to%d\n", Getpid (), Start,len);
}
}
}
4. Release the lock
void ReleaseLock (int fd,int start,int len)
{
struct flock arg;
Arg.l_type = F_unlck;
Arg.l_whence = Seek_set;
Arg.l_start = start;
Arg.l_len = Len;
if (fcntl (fd,f_setlkw,&arg) = =-1)
{
fprintf (stderr, "[%d] Unlock failed.\n", Getpid ());
}
Else
fprintf (stderr, "[%d]unlock from%d to%d\n", Getpid (), Start,len);
}
Fcntl File Lock operation