文件锁 记录锁

下面介绍两种两种Linux下对文件加锁的两种方式
一、文件锁
思想:
假设有一个文件A。创建一个加锁文件B,通过不同的进程互斥的访问此加锁文件B达到互斥的访问文件A的目的。
源码如下

二、记录锁
第二种方式可以实现只锁文件的某个部分,并且可以灵活的选择是阻塞方式还是立刻返回方式。

记录锁通过系统调用 fcntl来实现
#include <fcntl.h>
int fcntl(int fd, int command, long arg);

struct flock
{
 short l_type; // 锁的类型
 short l_whence;// 锁的起始
 off_t l_start;// 锁的起始偏移,与l_whence相关
 off_t l_len; // 锁住多少字节
 off_t l_pid; // 拥有锁的进程pid
}

调用fcntl进行加锁的操作时,arg是指向结构体flock的指针。
l_type表示加锁的类型,它可以是以下值:
F_RDLCK 读锁(共享锁)
F_WRLCK 写锁(独占锁)
F_UNLCK 释放锁

参数l_whence和l_start表示锁的起始地址,含义与lseek中的同名参数相同。
l_whence为以下三个值之一:
SEEK_SET: 从文件开始计算
SEEK_CUR: 从当前计算
SEEK_END:从文件末尾计算

参数
l_len表示锁的长度是多少字节,如果为0.表示锁一直延伸到文件按的末尾。
l_pid: 仅在查询锁的时候才用,它是这个锁的拥有者的进程pid

fcntl有三个命令和加锁有关,操作通过参数command来传递,它可以是以下的三个值之一:
F_SETLK: 按照arg进行加锁和解锁的处理,如果因为冲突不能上锁,立刻返回并且errno被设置为EAGAIN。
如果l_type是F_UNLCK,已存在的锁被释放。
F_SETLKW:相当于阻塞式的F_SETLK(W的含义是wait)。如果要上锁的区域被其他进程锁住,使申请不能马上成功,则进入睡眠,
等待原来的锁被释放,在上锁成功后返回,如果在进程阻塞时有信号发生,返回并且errno被设为EAGAIN
F_GETLK:检查是否可以申请由arg决定的锁。如果不和别的进程已经存在的锁发生冲突,arg指向的结构flock中的l_type被赋为
F_UNLCK,其余的成员不变。如果不能给与锁,l_pid被赋为发生冲突的进程的pid。这两种情况下函数都返回0。

下面是一些关于记录锁的规则:
1)锁可以延伸到文件按目前的结尾之后,但是不能扩展到文件头之前,也不能从文件头之前开始。
2)如果l_len为0,锁得到最大长度的延伸,这是我们可以从文件的任何地方开始,向后锁住所有的文件数据,并锁住以后添加到
文件末尾的数据,不管添加多少数据。
3)要锁住整个文件,设l_start为0,l_whence为SEEK_SET,l_len为0。
4)如果一块区域被一个进程加了读锁,则另外的进程可以再给它加上读锁,但是不能加写锁。(共享锁)。
如果一块区域被一个进程加了些锁,则它不能为另外的进程加上读锁或写锁(独占锁)。

5)锁的释放:
当进程终止时,它所有的锁都会被释放(不同与文件锁)。
当文件描述符关闭时,在这个进程中,加在该文件描述符上的所有锁被释放。


一下是示例代码:


以上是我一个字一个字打的,累了。不想多说了。不过以上也基本可以满足编程需求了。

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值