linux文件锁

1.struct flock介绍
结构体描述
锁类型: F_RDLCK(读共享锁), F_WRLCK(写互斥锁),和F_UNLCK(对一个区域解锁)
锁开始: 锁位置(l_whence),相对于l_whence要锁或者解锁的区域开始位置(l_start)
锁长度: 要锁的长度,字节计数(l_len)
锁拥有者:记录锁的拥有进程ID,这个进程可以阻塞当前进程,仅F_GETLK形式返回
struct flock
{
        short l_type;    /*F_RDLCK, F_WRLCK, or F_UNLCK*/
        off_t l_start;    /*相对于l_whence的偏移值,字节为单位*/
        short l_whence;    /*从哪里开始:SEEK_SET, SEEK_CUR, or SEEK_END*/
        off_t l_len;    /*长度, 字节为单位; 0 意味着缩到文件结尾*/
        pid_t l_pid;    /*returned with F_GETLK*/
};

2.fcntl函数介绍

fcntl系统调用可以用来对已打开的文件描述符进行各种控制操作以改变已打开文件的的各种属性
原型:int fcntl(int fd, int cmd ,struct flock* lock);
参数:
        fd是要锁定的文件描述符
        对于cmd参数,可以使用的有: F_GETLK, F_SETLK(较多使用)or F_SETLKW
        第三个参数(flockptr),指向一个flock结构指针
返回值:如果出错,返回-1,错误原因保存在错误码errno中,如果成功则返回某个其他值
注意:
        1)fcntl函数添加锁失败:errno=9, Bad file descriptor
        原因之一:打开文件方式为只读打开,却想添加写文件锁导致
        2)fcntl函数造成互斥的测试:一般是两个线程之间测试(一个线程上锁,另一个尝试去写)
        3)fcntl函数文件锁:两个线程之间同时上读锁不造成互斥,可以同时读取访问
        4)fcntl函数文件锁:两个不同线程对同一资源的文件描述符可以不一致(和资源的文件描述符是否相同无关)

//根据锁类型封装函数
#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))

int lock_reg(int fd, int cmd, int type, off_t offset, int whence, off_t len){
	struct flock lock;
	
	lock.l_type = type;
	lock.l_start = offset;
	lock.l_whence = whence;
	lock.l_len = len;
	return(fcntl(fd, cmd, &lock));
}
//核心代码
static int function_write()	//写文件锁
{
	/* 写文件前设置写锁 */
	if(write_lock(fileno(host_fp), 0, SEEK_SET, 0) == -1)
	{
		fprintf(stderr,"%s: write_lock fail: %s, sleep 5s, try again.\n", __FUNCTION__, strerror(errno));
		sleep(5);
		write_lock(fileno(host_fp), 0, SEEK_SET, 0);
	}
	/* 
    写操作
    ...
    ...
    ...
    */
	
	/* 写完后要释放锁 */
	if(un_lock(fileno(host_fp), 0, SEEK_SET, 0) == -1)
	{
		fprintf(stderr,"%s: unlock fail: %s, sleep 1s, try again.\n", __FUNCTION__, strerror(errno));
		sleep(1);
		un_lock(fileno(host_fp), 0, SEEK_SET, 0);
	}
}
static int function_read() //读文件锁
{
    if(read_lock(fileno(fp), 0, SEEK_SET, 0) == -1)
	{
		fprintf(stderr,"%s: read_lock fail: %s. sleep 5s, try again.\n", __FUNCTION__, strerror(errno));
		sleep(5);
		read_lock(fileno(fp), 0, SEEK_SET, 0);
	}
	/* 
    读文件操作
    ...
    ...
    ...
    */
	if(un_lock(fileno(fp), 0, SEEK_SET, 0) == -1)
	{
		fprintf(stderr,"%s: unlock fail: %s. sleep 1s, try again.\n", __FUNCTION__, strerror(errno));
		sleep(1);
		un_lock(fileno(fp), 0, SEEK_SET, 0);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值