”记录锁“更准确的叫法应该是”字节范围锁“,它可以锁住文件的部分字节,使不同进程间互斥地访问文件的这部分字节。同时,锁的属性是可以设置的,锁的类型分为以下三种:
- 共享读锁
- 独占写锁
- 解锁
当锁类型为共享读时,运行多个进程同时访问,因为是读,所以是安全的。当锁类型为独占写锁时,必须互斥地访问,因为此时进行的是写操作。
接下来看看记录锁在本数据库函数库中的应用,代码如下:
/* 记录所相关函数 */
int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len)
{
struct flock lock; /* 定义一个记录所 */
lock.l_type = type; /* 锁类型(F_RDLCK, F_WRLCK, F_UNLCK) */
lock.l_start = offset; /* 从whence处的偏移量 */
lock.l_whence = whence; /* 起始点 */
lock.l_len = len; /* 加锁区域长度 */
/* cmd:
* F_GETLK:测试能够建立一把锁
* F_SETLK:试图建立一把锁,不会阻塞
* F_SETLKW:试图建立一把锁,会阻塞
*/
return (fcntl(fd, cmd, &lock));
}
/* 非阻塞型读锁 */
#define read_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len))
/* 阻塞型读锁 */
#define readw_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLKW, F_RDLCK, (offset), (whence), (len))
/* 非阻塞型写锁 */
#define write_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_WRLCK, (offset), (whence), (len))
/* 阻塞型写锁 */
#define writew_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))
/* 解锁 */
#define un_lock(fd, offset, whence, len) \
lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))
lock_reg函数根据参数设置不同的锁,然后调用系统调用fcntl使锁生效。实际上记录锁就是一个struct flock结构体,对它的设置在代码的注释中已经说明了,这里不再详述。为了方便函数库内部调用,这里把需要的不同类型的锁做成了宏的形式,需要什么样的锁就调用对应的宏。
更多关于记录锁在内容,参考《unix环境高级编程》14.3节。