- 论坛徽章:
- 0
|
求助 fcntl 锁文件的问题
l_type:锁的类型.
F_RDLCK读锁(共享锁)
F_WRLCK写锁(独占锁)
锁的分类可以分为强制性锁和建议性锁两种,强制型锁不需要在采取其它措施就自动起到互斥作用;建议性锁仅起到告示作用.在使用建议性锁时,进程需要监测文件相关部分是否上了锁,然后在决定是否对其进行读写操作,这样也能起到若干个进程对相关文件部分进行互吃的对写操作.
使用chmod和fcntl的F_SETLK命令相结合可以设置强制性锁;单独调用fcntl的F_SETLK的命令只能设置建议性锁.
chmod +l example
从操作类型可以将锁分为读锁和写锁;在使用fcntl的的F_SETLK命令设置锁时,使用锁类型F_RDLK, F_WRLK指定.
锁的合并:
若不同进程需要设置的两把锁作用范围部分或全部重叠,则先设置的读锁阻止后来设置的;先设置的写锁阻止后来的读/写锁.若同一进程先后要求设置的两把锁(A,B)的作用范围部分或全部重叠,则在两把锁同类的情况下,它们的作用范围合并成一把锁(AUB);若两把锁不同类,则后设置的锁覆盖先设置的锁,先设置的锁的范围变成(AUB) - B.锁的互斥,合并及覆盖与是建议性还是强制型锁无关.
强制性读锁能阻止其它进程对相应文件(或记录)进行写操作;强制性写锁能阻止其它进程进行读/写操作.
为了检测文件的上锁情况,应当使用fcntl的F_GETLK命令.
可以使用带锁类型F_UNLCK的F_SETLK命令清除锁的部分或全部.当文件关闭或进程中止时,它所设置的锁全部自动清除.一个进程不能清除其它进程所加的锁.
F_UNLCK (释放锁)
参数l_whence和l_start标识锁的起始地址,含义与lseek的同名参数相同.l_whence可以是SEEK_SET(从文件头开始), SEEK_CUR(从当前位置开始),SEEK_END(从文件结尾计算).
参数l_len标识锁的长度是多少字节,如果为0,则表示锁一直延伸到文件结尾.
l_pid,仅在查询锁时才有用,它是锁的拥有者的pid.
F_SETLK:按照参数进行加锁和解锁的处理.如果因为冲突无法上锁,立即返回并且errno被赋值为EAGAIN.如果l_type是F_UNLCK,以存在的锁被释放.
F_SETLKW:相当于阻塞的F_SETLK(W的含义就是等待wait).如果要上锁的区域被其它进程锁住,使申请没有马上成功,则进程进入睡眠,等待原来的锁被释放,在上锁成功后返回.如果在进程阻塞时有信号发生,返回并且设置errno为EAGAIN.
F_GETLCK:检查是否可以申请由arg制定的锁.如果不和别的进程已经存在的锁发生冲突,arg所指向的flock的l_type被赋值为F_UNLCK,其它成员不变.如果不能给予锁,l_pid被赋值为发生冲突的进程的pid,这两种情况下,函数都返回0.
接着谈一下你的代码吧.
首先,你创建的一个建议性的写锁.接着使用F_GETLK测试是否允许在加一个写锁,注意我上面所提到的锁的合并条件,由于位于同一进程中,并且锁类型相同(写锁),作用范围合并成一把新锁(还是一样的)范围,
首先测试是否可以加写锁,经测试可以,所以输出before lock l_type=2,l_pid=0(l_type=2也就是允许加写锁);
然后使用阻塞方式加一个建议性的写锁,成功.
然后在此测试是否可以加写锁.注意我上面所提到的锁的合并条件,由于位于同一进程中,并且锁类型相同(写锁),作用范围合并成一把新锁(还是一样的)范围.所以在此输出时,仍旧输出l_type=2,l_pid=0.
所以你的get_lock_status并不是获得锁的状态,实际上仅仅是一个是否可锁的测试.
要确定锁的类型,我觉得还是用
- if (lock.l_type == F_RDLCK)
- 是读锁;
复制代码
等语句来确定.[/code] |
|