当前位置: 首页 > news >正文

Linux 文件锁

1 为什么用文件锁

文件是一种共享资源,多个进程对同一文件进行操作的时候,必然涉及到竞争状态,因此引入了文件锁实现对共享资源的访问进行保护的机制,通过对文件上锁, 来避免访问共享资源产生竞争状态

2 文件锁用法

(1)参考文档:
man 2 fcntl

(2)头文件:
#include <unistd.h>
#include <fcntl.h>

(3)函数定义
int fcntl(int fd, int cmd, … /* arg */ );

(4)参数:

cmd 取值:
F_GETLK 获取锁
F_SETLK 设置锁
F_SETLKW 同步设置锁

(5)文件锁struct flock的定义:

struct flock {short l_type; 		//锁的类型(F_RDLCK(读锁), F_WRLCK(写锁),  F_UNLCK (解锁))off_t l_start; 		//指明文件加锁的开始位置(同l_whence)short l_whence;		//标志文件锁的初始位置(SEEK_SET, SEEK_CUR,  SEEK_END) off_t l_len; 		//加锁的长度(字节), 0表示整个文件 pid_t l_pid; 		//是加锁进程的进程 id。
}

3应用举例


#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>#define FILE_NAME "flock_demo.txt"int flock_set(int fd, int type) {printf("进程pid=%d 来啦!\n",getpid());//创建文件锁struct flock fflock;memset(&fflock,0,sizeof(struct flock));fcntl(fd,F_GETLK,&fflock);//文件已经获过取锁了if (fflock.l_type != F_UNLCK) {//文件已上锁if (fflock.l_type == F_RDLCK) {//文件的上读锁printf("抱歉,进程%d已经加上读锁!\n",fflock.l_pid);}else if(fflock.l_type == F_WRLCK)//文件上写锁{printf("抱歉,进程%d已经加上写锁!\n", fflock.l_pid);} }//配置文件锁fflock.l_type = type;		//锁的类型fflock.l_whence = SEEK_SET;	//文件头fflock.l_start = 0;			//锁字节为单位的偏移fflock.l_len = 0;			//锁多长内容(0表示整的文件)fflock.l_pid = -1;if (fcntl(fd,F_SETLKW, &fflock)<0){printf("上锁失败!\n");return -1;}switch (fflock.l_type){case F_RDLCK:printf("进程%d加上读锁成功!\n", getpid());break;case F_WRLCK:printf("进程%d加上写锁成功!\n", getpid());break;case F_UNLCK:printf("进程%d已解锁成功!\n", getpid());break;default:break;}printf("进程pid=%d退出\n",getpid());return 0;
}int main(void) {int fd=0;fd = open(FILE_NAME,O_RDWR|O_CREAT,0666);if (fd<0) {fprintf(stderr,"打开文件%s失败,错误原因%s\n", FILE_NAME,strerror(errno));exit(-1);}flock_set(fd, F_WRLCK);	//对打开的文件写锁getchar();flock_set(fd, F_UNLCK);	//对打开的文件解锁getchar();close(fd);return 0;
}

运行效果:
在这里插入图片描述

注意:可以同时对文件进行加读锁不受影响,单对文件加写锁则会互斥

http://www.lryc.cn/news/246727.html

相关文章:

  • 原理Redis-SkipList
  • Express内置的中间件
  • Webstorm 插件文件目录颜色分析——白蓝绿红黄灰
  • 蓝桥杯day01——根据给定数字划分数组
  • oracle数据库巡检常见脚本-系列二
  • JavaScript 表达式
  • Python之Pygame游戏编程详解
  • 虚拟摇杆easytouch joystick的方向与角色移动方向不一致
  • C++二分查找:统计点对的数目
  • 播放器开发(二):了解FFmpeg与SDL常用对象和函数
  • 【数据库】基于排序算法的去重,集合与包的并,差,交,连接操作实现原理,执行代价以及优化
  • Redis 主从架构,Redis 分区,Redis哈希槽的概念,为什么要做Redis分区
  • 极客大挑战2023 Web方向题解wp 全
  • kafka开发环境搭建
  • Python大数据考题
  • 才聚免费为你招聘,用人单位看过来!
  • 【SpringCloud】微服务的扩展性及其与 SOA 的区别
  • 从零带你底层实现unordered_map (2)
  • 打造企业AI数字人专属IP的重要性
  • docker容器的生命周期管理常用命令
  • CF 1900B Laura and Operations 学习笔记
  • Linux学习笔记6-串口应用
  • ubuntu下如何查看.gz压缩包中的内容,以及grep过滤查找文件中的某些内容
  • AI 重构工业制造的故事 我们从大模型开始讲起
  • easyExcel 注解开发 快速以及简单上手 以及包含工具类
  • VS2010配置opencv2.4.10
  • Android:控制按键灯亮灭【button-backlight】
  • 1、nmap常用命令
  • Redis缓存设计典型问题
  • 【python】python基础速通系列2-python程序中的积木块