加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

UNIX环境高级编程:记录上锁(fcntl函数)以及死锁检测

发布时间:2016-09-27 12:24:10 所属栏目:Unix 来源:站长网
导读:副标题#e# 一、记录锁 record locking 功能:当一个进程正在读或修改文件的某个部分时,它可以阻止其它进程修改同一文件区。 字节范围锁 byte-range locking 二、历史 flock函数,可以锁整个文件,不能锁文件中的一部分。 fcntl函数,增加了记录锁的功能。
副标题[/!--empirenews.page--]

一、记录锁 record locking

功能:当一个进程正在读或修改文件的某个部分时,它可以阻止其它进程修改同一文件区。

字节范围锁 byte-range locking

二、历史

flock函数,可以锁整个文件,不能锁文件中的一部分。

fcntl函数,增加了记录锁的功能。

lockf函数,在fcntl基础上构造了lockf函数,提供一个简化的接口。可以锁文件中任意字节数的区域

三、fcntl 记录锁

函数原型:

int fcntl(int fd, int cmd, struct flock *flockptr);  
      
      
/* 
cmd = F_GETLK,测试能否建立一把锁 
cmd = F_SETLK,设置锁 
cmd = F_SETLKW, 阻塞设置一把锁 
     
     
*/
//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 命令有效) */
      /*...*/
};

(1)所希望的锁类型:F_RDLCK(共享读锁)、F_WRLCK(独占性写锁)、F_UNLCK(解锁一个区域)。

(2)要加锁或解锁区域的起始字节偏移量由l_start和l_whence两者决定。

(3)注意:该区域可以在当前文件尾端开始或越过其尾端处开始,但是不能在文件起始位置之前开始。

(4)如若l_len为0,则表示锁的区域从其起点(由l_start和l_whence决定)开始直至最大可能偏移量为止。

(5)为了锁住整个文件,我们设置l_start和l_whence,使锁的起点在文件起始处,并说明长度(l_len)为0。

上面提到了两种类型的锁:共享读锁(F_RDLCK)和独占写锁(F_WRLCK),基本规则是:

多个进程在一个给定的字节上可以有一把共享的读锁,但是在一个给定字节上只能有一个进程独用的一把写锁。进一步而言,如果在一个给定字节上已经有一把或多把读锁,则不能再该字节上再加写锁;如果在一个字节上已经有一把独占性的写锁,则不能再对它加任何读锁。    

不同进程锁请求的读写锁规则:

-------------------                   加读锁         加写锁

无锁                                      允许             允许

一个或多个读锁                    允许             拒绝

一个写锁                              拒绝             拒绝

注意:上面这个规则适用于不同进程提出的锁请求,并不适用于单个进程提出的多个锁请求。单个进程提出多个锁请求的时候,以最后一次锁作为标准,即新锁替换旧锁对于同一文件,如果一直有不同的进程连续的对其添加读锁,则其它欲对其添加阻塞写锁的进程有可能延长等待时间(这样的情况,对于添加写锁的进程会出现饿死情况)。

在读锁时,该描述符必须是读打开;加写锁时,该描述符必须是写打开。

F_GETLK: 判断由flockptr所描述的锁是否会被另外一把锁所排斥(阻塞)。如果存在一把锁,它阻止创建由flockptr所描述的锁,则把该现存锁的信息写到flockptr指向的结构中。如果不存在这种情况,则除了将l_type设置为F_UNLCK之外,flockptr所指向结构中的其他信息保持不变。

F_SETLK : 获取(l_type为F_RDLCK或F_WRLCK)或释放由flockptr指向flock结构所描述的锁,如果无法获取锁时,该函数会立即返回一个EACCESS或EAGAIN错误,而不会阻塞。

F_SETLKW:  F_SETLKW和F_SETLK的区别是,无法设置锁的时候,调用线程会阻塞到该锁能够授权位置。

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

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读