【Linux】记录锁

什么是记录锁?试想这样一种情况,当多个人同时编辑一个文件时会发生什么?如Microsoft Office就提供了共享功能,支持多人同时编辑,但有时候我们希望同时只有一人能够编辑,比如说数据库文件,这时记录锁就派上用场了,确切的说记录锁是一种字节范围锁,锁定的是文件中的某个区域或整个文件。当一个进程正在读或修改文件的某个部分时,记录锁可以阻止其它进程修改同一文件区。fcntl函数可以实现这一功能。

#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

fcntl参数的fd为待处理文件描述符,cmd是一系列命令参数,对于记录锁而言,cmd为F_GETLK(共享读锁)、F_SETLK(独占性写锁)或F_SETLKW(解锁),第三个参数是一个指向flock结构的指针,flock结构如下:

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) */
               ...
};

多个进程在一个给定的字节上可以有一把共享的读锁,但是在一个给定字节上只能有一个进程独用的一把写锁。如果在一个给定的字节上已经有一把或多把读锁,则不能在该字节上再加写锁;如果在一个字节上已经有一把独占性的写锁,则不能再对它加任何读锁。F_GETLK用于测试能否建立一把锁,F_SETLKW与F_SETLK的区别是前者有阻塞功能。

记录锁可以自动继承,也会自动释放,规则如下:
(1)当一个进程终止时,它所建立的锁全部释放。
(2)任何时候关闭一个描述符时,则该进程通过这个描述符可以引用的文件上的任何一把锁都被释放。
(3)由fork产生的子进程不继承父进程所设置的锁。
(4)在执行exec后,新程序可以继承原执行程序的锁。但是如果一个文件描述符设置了close-on-exec标志,那么当作为exec的一部分关闭该文件描述符时,对相应文件的所有锁都被释放了。

记录锁有建议性锁和强制性锁两种机制,它们并不是真正的锁,而是一种能对记录锁的效果产生影响的机制。
建议性锁:每个使用文件的进程都要主动检查该文件是否有锁存在,当然都是通过具体锁的API,比如fcntl记录锁F_GETTLK来主动检查是否有锁存在。如果有锁存在并被排斥,那么就主动保证不再进行接下来的IO操作。如果每一个进程都主动进行检查,并主动保证,那么就认为这些进程都以一致的方法处理锁,是合作的。但是,不主动判断这个文件有没有加上记录锁,就直接对这个文件进行IO操作,会怎么样呢?这种有破坏性的IO操作会不会成功呢?如果是在建议性锁的机制下,这种破坏性的IO就会成功。因为锁只是建议性存在的,并不强制执行。
强制性锁:文件记录锁功能由内核执行,上述提到的破坏性IO操作会被内核禁止。当文件被加锁来进行读写操作时,在锁定该文件的进程释放该锁之前,内核会强制阻止任何对该文件的读或写的违规访问,每次读或写访问都得检查锁是否存在,也就是强制性锁机制,让锁变得名副其实,真正达到了锁的效果。

Linux默认为建议性锁,开启强制性锁时,要对一个特定文件打开其设置组ID位并关闭其组执行位,如下:

$chmod g+s <FileName>
$chmod g-x <FileName>
相关推荐
©️2020 CSDN 皮肤主题: 我行我“速” 设计师:Amelia_0503 返回首页