首页 > 代码库 > ubuntu系统之难
ubuntu系统之难
要讲解记录锁机制,首先要介绍fcntl函数,如下给出该函数原型:
#include <fcntl.h> int fcntl(int filedes, int cmd, ... /* struct flock *flockptr */)函数返回值:若成功则依赖于cmd,若出错则返回-1。
对于记录锁,cmd是F_GETLK, F_SETLOCK, F_SETLKW。第三个参数(称其为flockptr)是一个指向flock结构的指针:
struct flock { short l_type; /* F_RDLCK, F_WRLCK, or F_UNLCK */ off_t l_start; /* offset in bytes, relative to l_whence */ short l_whence; /* SEEK_SET, SET_CUR, or SEEK_END */ off_t l_len; /* length, in bytes; 0 means lock to EOF */ pid l_pid; /* returned with F_GETLK */ };对flock结构说明如下:
- 所希望的锁类型:F_RDLCK(共享读锁),F_WRLCK(独占性写锁) 或则 F_UNLCK(解锁一个区域)
- 要加锁或解锁区域的起始字节偏移,这由l_start和l_whence两者决定。
- 区域的字节长度,由l_len表示。
- 具有能阻塞当前进程的锁,其持有进程的ID存放在l_pid中(仅由F_GETLK返回)。
- l_stat是相对偏移量(字节),l_whence则决定了相对偏移量的起点。这与lseek函数中最后两个参数类似。
- 该区域可以在当前文件尾端处开始或越过其尾端处开始,但是不能在文件起始位置之前开始。
- 如若l_len为0,则表示锁的区域从其起点(由l_start和l_whence两者决定)开始直至最大可能偏移量为止,也就是不管添写到该文件中多少数据,它们都在锁的范围内(不必猜测会有多少字节被追加到文件之后)。
- 为了锁整个文件,我们设置l_start和l_whence,使锁的起点在文件起始处,并且说明长度(l_len)为0。
F_GETLK:判断由flockptr锁描述的锁是否会被另外一把锁所排斥(阻塞)。如果存在一把锁,它阻止创建由flockptr所描述的锁,则把该现存锁的信息写到flockptr指向的结构中。如果不存在这种情况,则将l_type设置为F_UNLOCK外,flockptr所指向结构的其他信息保持不变。
F_SETLK:设置由flockptr所描述的锁。如果试图建立一把读锁(l_type设为F_RDLCK)或写锁(l_type设为F_WRLCK),而按兼容性规则不能允许的情况,fcntl立即出错返回,此时errno设置为EACCES或EAGAIN。此命令也用来清除由flockptr说明的锁(l_type为F_UNLCK)。
F_SETLKW:这是F_SETLK的阻塞版本。如果因为当前在请求区间的某个部分另一个进程已经有一把锁,因而按兼容性规则由flockptr所请求的锁不能被创建,则使调用进程休眠。如果请求创建的锁已经可用,或者休眠由信号中断,则该进程被唤醒。
实际编程中,为了避免每次分配flock结构,然后又填入各项信息,可以用如下函数两处理所有这些细节:
#include <fcntl.h> 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; /* byte offset, relative to l_whence */ lock.l_whence = whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ lock.l_len = len; /* #bytes (0 means to EOF) */ 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))
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。