linux 文件记录锁详解

一: linux记录锁更恰当的称呼应该是范围锁,它是对文件某个范围的锁定。

 

关于记录锁的功能就是fcntl提供的第五个功能,具体使用如下:

int fcntl(int fd, int cmd, struct flock *lock);

cmd = F_GETLK, 主要用来检测是否有某个已存在锁会妨碍将新锁授予调用进程,
        如果没有这样的锁,
lock所指向的flock结构的l_type成员就会被置成F_UNLCK
        否则已存在的锁的信息将会写入
lock所指向的flock结构中cmd = F_SETLK,设置锁
cmd = F_SETLK, 设置(l_typeF_RDLCKF_WRLCK)或释放由lock指向flock结构所描述的锁,
        如果无法设置锁时,该函数会立即返回一个
EACCESSEAGAIN错误,而不会阻塞。

cmd = F_SETLKW, F_SETLKWF_SETLK的区别是,无法设置锁的时候,调用进程程会阻塞到该锁
         能够授权位置。

这里需要注意的是,用F_GETLK测试能否建立一把锁,然后接着用F_SETLKF_SETLKW企图建立一把锁,
由于这两者不是一个原子操作,所以不能保证两次
fcntl之间不会有另外一个进程插入并建立一把相关的锁,
从而使一开始的测试情况无效。所以一般不希望上锁时阻塞,会直接通过调用
F_SETLK,并对返回结果进行
测试,以判断是否成功建立所要求的锁。


//POSIX标准只定义fock结构中必须有以下的数据成员,具体实现可以增加
struct flock { short l_type; /* 锁的类型: F_RDLCK, F_WRLCK, F_UNLCK */ short l_whence; /* 加锁的起始位置:SEEK_SET, SEEK_CUR, SEEK_END */ off_t l_start; /* 加锁的起始偏移,相对于l_whence */ off_t l_len; /* 上锁的字节数*/ pid_t l_pid; /* 已经占用锁的PID(只对F_GETLK 命令有效) */ /*...*/ };

文件记录锁操作规范图:


二: 文件记录锁位于V-node table这个结构中,使用PID作为锁拥有者的标识。这使其拥有如下特点:

1) 记录锁采用(PID, start,end)三元组作为锁标识,一个文件可拥有多个记录锁,同一区域只允许有一个记录锁。

2) 当进程终止(正常/不正常),该进程拥有的所有记录锁都将释放。

3) 同一个进程中,指向同一文件(i-node)的fd都可以操作该文件上的记录锁:如释放、修改等。显式调用F_UNLCK和close(fd)都将释放锁,close将释放整个文件中该进程拥有的所有记录锁。

4) 记录锁不被fork的子进程继承(PID不同)。

5) 记录锁的类型转换、改变锁范围等操作均为原子的。

6) 未设置FD_CLOEXEC时,记录锁将被exec后的进程继承(PID相同)。

7) 记录锁对文件打开mode有要求:加读锁要求fd有读权限;加写锁要求fd有写权限。

 

 

posted @ 2013-08-24 01:51  夕相待  阅读(3948)  评论(0编辑  收藏  举报