Linux mutual exclusion and synchronization application (vi): File lock

Source: Internet
Author: User
Tags flock flock lock

"Copyright Notice: respect for the original, reproduced please retain the source: blog.csdn.net/shallnet or .../gentleliu, the article is for learning communication only, do not use for commercial purposes"
When there are multiple processes in a system operating the same file at the same time, in order to ensure that the data is correct,files are typically locked to avoid the competitive state of shared files. File locks can be implemented using the FCNTL function in Linux systems. The function Fcntl prototype is as follows:
       #include <unistd.h>       #include <fcntl.h>       int fcntl (int fd, int cmd, .../* arg */);
function to open the file descriptor fd, according to different CMD commands to perform different operations, the command for the file lock is as follows:F_gtelk, F_SETLK, f_setlkw three kinds, respectively, to obtain the lock, set the lock, sync to get the lock. The function uses a file lock when the third parameter is a pointer to struct struct flock, which is defined roughly as follows:
           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) */                ...           };
Membersl_whence,l_start,L_len Specify the range of files we expect to lock; l_whence desirable values: Seek_set, Seek_cur, seek_end, generally set to Seek_set. L_start the offset at which to start the file lock, which is typically set to 0, at the beginning.
L_len Specifies the number of bytes to lock, if 0 indicates from the beginning to the end of the file.
L_pid is the process ID number holding the lock. L_type is the type to be locked, the value f_rdlck (read lock),F_wrlck (write lock),f_unlck (Release lock) can be taken.
Any number of processes can hold a read lock on the same file area, but only one process holds a write lock on it (exclusive lock). A single process can hold only one lock on the same file area, and if the new lock is applied to the same piece of the resulting file area, the previously existing lock is overwritten.
F_stelk requests a lock at L_type for F_rdlck or F_wrlck, and a lock is released in l_type for F_unlck, If there is another process already in advance and gets to the lock at this time, the call returns-1 immediately. < Span style= "line-height:1.5" > f_setlkw and f_stelk, the function call blocks until a lock is present until the lock is released. If the blocking period is interrupted, the signal interruption will be returned immediately. < Span style= "line-height:1.5" > F _gtelk for Point to struct flock struct type lock to try to lock, If the lock can be added (an operation that does not actually do a lock), the Fcntl () function l_type in the struct to f_unlck , the remaining members remain unchanged. If there is an incompatible lock that prevents this type of lock-lock, Fcntl writes the details of the existing lock to the struct, where l_pid is the process ID holding the lock. &NBSP; < Span style= "line-height:1.5" > < Span style= "line-height:1.5" >
/span> < Span style= "line-height:1.5" > < Span style= "line-height:1.5" > If you want to read the lock on the file area, the file description should be opened in a readable manner, similarly, if the folder is written to lock, the file should be opened in a writable manner. < Span style= "line-height:1.5" > < Span style= "line-height:1.5" >
/span> < Span style= "line-height:1.5" > < Span style= "line-height:1.5" > file lock release There are three ways, one is to display the use of F_unlck type lock, the second is the process of termination, and the third is all open for the file description of the file is closed. < Span style= "line-height:1.5" > < Span style= "line-height:1.5" >
/span> file locks are not inherited by child processes that are generated by fork ().
The following is the locking, Sync locking, unlock, test read-write lock API that is implemented by wrapping the FCNTL function:
/** * \brief acquire, release or test for the existence of record locks * \details If a conficling are held on the fi Le, then return-1. * * \param fd-file Descriptor * \param locktype-lock Type:f_rdlck, F_wrlck, F_unlck. * * \return 0 is success, < 0 is failed.    */static int sln_filelock_set (int fd, short locktype) {struct flock lock;    Lock.l_type = LockType;    Lock.l_whence = Seek_set;    Lock.l_start = 0;    Lock.l_len = 0;    Lock.l_pid = Getpid ();        if (Fcntl (FD, F_SETLK, &lock) < 0) {fprintf (stderr, "Fcntl:%s\n", Strerror (errno));    return-1; } return 0;} /** * \brief acquire, release or test for the existence of record locks * \details If a conficling are held on the fi Le, then wait-for-that * lock-to-be release * * \param fd-file Descriptor * \param locktype-lock ty Pe:f_rdlck, F_wrlck, F_unlck. * * \return 0 is success, < 0 is failed. */int sln_filelock_wait_set (int fd, short LockType{struct flock lock;    Lock.l_type = LockType;    Lock.l_whence = Seek_set;    Lock.l_start = 0;    Lock.l_len = 0;    Lock.l_pid = Getpid ();        if (Fcntl (FD, F_SETLKW, &lock) < 0) {fprintf (stderr, "Fcntl:%s\n", Strerror (errno));    return-1; } return 0;} int sln_file_wrlock (int fd) {return Sln_filelock_set (FD, F_WRLCK);} int sln_file_rdlock (int fd) {return Sln_filelock_set (FD, F_RDLCK);} int sln_file_wait_wrlock (int fd) {return Sln_filelock_wait_set (FD, F_WRLCK);} int sln_file_wait_rdlock (int fd) {return Sln_filelock_wait_set (FD, F_RDLCK);} int sln_file_unlock (int fd) {return Sln_filelock_set (FD, F_UNLCK);} /** * \brief test for the existence of record locks on the file * \details None * * \param Fd-file Descriptor * \param Locktype-lock Type:f_rdlck, F_wrlck. * * \return 0 is success, < 0 is failed.    */static int sln_filelock_test (int fd, short locktype) {struct flock lock;    Lock.l_type = LockType; Lock.l_whence = 0;    Lock.l_start = 0;    Lock.l_len = 0;    lock.l_pid = 0;        if (Fcntl (FD, F_GETLK, &lock) < 0) {fprintf (stderr, "Fcntl:%s\n", Strerror (errno));    return-1; if (lock.l_type! = F_unlck) {//file is locked if (f_wrlck = = Lock.l_type) {printf ("Write lock Hol        d by Process <%d>, Lock_type:%d\n ", Lock.l_pid, Lock.l_type); } else if (F_rdlck = = Lock.l_type) {printf ("read lock hold by Process <%d>, Lock_type:%d\n", Lock.l_pid        , Lock.l_type); } return lock.l_pid;        Return the PID of process holding that lock} else {printf ("Unlock, lock Type:%d\n", Lock.l_type);    return 0; }}int sln_file_wrlock_test (int fd) {return sln_filelock_test (FD, F_WRLCK); int sln_file_rdlock_test (int fd) {return sln_filelock_test (FD, F_RDLCK);}

The following three processes are implemented, and three processes read, write, and test the lock operation for the same file:Write Process:
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include < string.h> #include <errno.h> #include "filelock.h" int main (int argc, const char *argv[]) {    int             fd;    if (argc! = 2) {        fprintf (stderr, "Usage:%s <write_str>\n", argv[0]);        return-1;    }    FD = open ("Filelock.txt", O_RDWR | O_creat, 0644);    if (FD < 0) {        fprintf (stderr, "Open:%s\n", Strerror (errno));        return-1;    }    if (Sln_file_wait_wrlock (FD) < 0) {        printf ("Lock write failed!\n");        Close (FD);        return-1;    }    printf ("Process <%d> holding write lock ok!\n", Getpid ());    Write (FD, argv[1], strlen (argv[1]));    Sleep (ten);    Sln_file_unlock (FD);    printf ("Release lock!\n");    Close (FD);    return 0;}

Read process:
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include < string.h> #include <errno.h> #include "filelock.h" int main (int argc, const char *argv[]) {    int             fd;    Char            buf[1024];    FD = open ("Filelock.txt", O_rdonly | O_creat, 0644);    if (FD < 0) {        fprintf (stderr, "Open:%s\n", Strerror (errno));        return-1;    }    if (Sln_file_wait_rdlock (FD) < 0) {        printf ("Lock read failed!\n");        Close (FD);        return-1;    }    printf ("Process <%d> holding read lock ok!\n", Getpid ());    Sleep (ten);    Read (FD, buf, sizeof (BUF));    printf ("Read buf:%s\n", buf);    Sln_file_unlock (FD);    printf ("Release lock!\n");    Close (FD);    return 0;}
To test the read-write lock process:
#include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include < string.h> #include <errno.h> #include "filelock.h" int main (int argc, const char *argv[]) {    int             fd, pid;< C2/>FD = open ("Filelock.txt", O_RDWR | O_creat, 0644);    if (FD < 0) {        fprintf (stderr, "Open:%s\n", Strerror (errno));        return-1;    }    PID = Sln_file_wrlock_test (FD);    if (PID > 0) {        printf ("Write locked!\n");    } else {        printf ("Write unlock!\n");    }    PID = Sln_file_rdlock_test (FD);    if (PID > 0) {        printf ("Read locked!\n");    } else {        printf ("Read unlock!\n");    }    Close (FD);    return 0;}

Compile and run three programs.to test the effect, read and write sleep in the process for 10 seconds. 1. In the presence of a write lock, a read lock cannot be held. Test: Run the write process before the read process is run, and the read process will get the lock when the write process releases the lock. 2. When a read lock is present, the write lock cannot be held. Test: The read process is run before the write process is run, and the write process obtains the lock when the read process releases the lock. 3. In the presence of a read lock, additional read locks can continue to be held. Test: Run two read processes, and then run the read process can immediately get read lock. 4. The above test can also be used to test the read-write lock process to obtain results.
SOURCE download: Click to open the link

Linux mutual exclusion and synchronization application (vi): File lock

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.