Linux 文件I/O(三)之fcntl记录锁
上篇已经介绍了fcntl的部分用法,现在我们重点看一下fcntl函数的文件锁功能!
函数原型
int fcntl(int fd, int cmd, ... /* arg */ )
返回值
获得/设置记录锁的功能,成功则返回0,若有错误则返回-1,错误原因存于errno。参数
在介绍参数之前先讲一下有助理解的一些知识。
结构体flock的指针:
struct flcok
{
short int l_type; /* 锁定的状态*/
//以下的三个参数用于分段对文件加锁,若对整个文件加锁,则:l_whence=SEEK_SET, l_start=0, l_len=0
short int l_whence; /*决定l_start位置*/
off_t l_start; /*锁定区域的开头位置*/
off_t l_len; /*锁定区域的大小*/
pid_t l_pid; /*锁定动作的进程*/
};
l_type 有三种状态:
F_RDLCK 建立一个供读取用的锁定
F_WRLCK 建立一个供写入用的锁定
F_UNLCK 删除之前建立的锁定
F_WRLCK 建立一个供写入用的锁定
F_UNLCK 删除之前建立的锁定
l_whence 也有三种方式:
SEEK_SET 以文件开头为锁定的起始位置
SEEK_CUR 以目前文件读写位置为锁定的起始位置
SEEK_END 以文件结尾为锁定的起始位置
SEEK_CUR 以目前文件读写位置为锁定的起始位置
SEEK_END 以文件结尾为锁定的起始位置
文件锁包括建议性锁和强制性锁。一般情况下,内核和系统都不适用建议性锁,采用强制性锁的影响很大,每次读写操作都必须检查是否有锁存在。实现文件上锁的函数有lockf() 和fcntl() ,其中lockf()用于对文件施加建议性锁,而fcntl() 不仅可以施加建议性锁,而且可以施加强制性锁。fcntl()还能对文件的某一记录上锁,也就是记录锁。记录锁又可分读取锁(共享锁)和写入锁(排斥锁),文件的同一部分不能同时建立读取锁和写入锁。
共享锁:你可以加共享锁,它也可以加,若干进程读的时候他们互不影响,设立共享锁的目的是避免该锁定区域被其它进程独占。但是共享锁并不是read-only只读的!其它进程如果有此文件的写权限,那么它仍然可以对此区域进行写操作。
写入锁:如果用户申请了一个互斥锁定,其他进程都无法对该文件进行锁定。
举个例子:进程A对某文件一部分设置了共享锁,进程B也可以对该部分设置共享锁,但不能设置写入锁。进程A对某文件的一部分设置了写入锁,其它进程不能再对该部分设置锁。
F_SETLK:
这个命令用来实施 “锁定” 或 “解锁” 动作( 由文件描述符指定文件 )。flock 结构中的值( 不同于从F_GETLK 中的值) 如下:
l_type
l_pid (未用)
l_type 有三个值:
F_RDLCK : 共享锁,只读用
F_WRLCK : 独占锁(写操作锁)
F_UNLCK : 解除锁定
和 F_GETLK 一样,区域锁定同样用 l_start, l_whence 和 l_len 这三个值( 在 flock 结构体中 )来定义。如果锁操作成功,fcntl() 返回一个值( 执行了马上就能返回 ),否则返回 -1 。
这个命令用来实施 “锁定” 或 “解锁” 动作( 由文件描述符指定文件 )。flock 结构中的值( 不同于从F_GETLK 中的值) 如下:
l_type
l_pid (未用)
l_type 有三个值:
F_RDLCK : 共享锁,只读用
F_WRLCK : 独占锁(写操作锁)
F_UNLCK : 解除锁定
和 F_GETLK 一样,区域锁定同样用 l_start, l_whence 和 l_len 这三个值( 在 flock 结构体中 )来定义。如果锁操作成功,fcntl() 返回一个值( 执行了马上就能返回 ),否则返回 -1 。
F_SETLKW:
F_SETLKW 的作用和上面的 F_SETLK 一样,不同的是如果无法锁定那它就会一直等待直到可以锁定为止;一旦进入等待状态,则这个函数只有在被可以进行锁定或者是接收到信号时才会返回。
测试代码就先不写啦!