文件控制操作

简介: 文件控制操作

在实际应用中,经常会遇到多个程序同时操作一个文件的情况,专业术语为:文件共享,有时也称为竞态Linux 中通常采用的方式是对文件上锁,以解决对共享资源的竞争。


文件锁包括建议性锁强制性锁。建议性锁要求每个相关程序在访问文件之前检查是否有锁存在,并且尊重已有的锁。而强制性锁是由内核执行的锁,当程序对文件上锁并执行写入操作时,内核将阻止其他程序对该文件进行读写操作。采用强制性锁对性能的影响较大,每次读写操作内核都检查是否有锁存在


Linux 中,实现文件上锁的函数有 lockf()fcntl() ,其中 lockf() 函数用于对文件施加建议性锁,而 fcntl() 函数不仅可以施加建议性锁,还可以施加强制性锁。同时, fcntl() 函数还能对文件的某一记录上锁,也就是记录锁


记录锁又可以分为读取锁写入锁,其中读取锁又称为共享锁,多个同时执行的程序允许在文件的同一部分建立读取锁。而写入锁又称为排斥锁,在任何时刻只能有一个程序在文件的某个部分建立写入锁。显然,在文件的同一部分不能同时建立读取锁和写入锁。


fcntl() 函数具有丰富的功能,它可以对已打开的文件进行各种操作,不仅能够管理文件锁,还可以获取和设置文件相关标志位,以及复制文件描述符等。


语法如下:

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, .../* arg */);点击复制复制失败已复制


参数 fd文件描述符,参数 cmd 用来实现函数不同的功能。 cmd 功能设置如下所示:

cmd 功能
F_DUPFD 复制一个现存的描述符
F_GETFDF_SETFD 获取或设置文件描述符标记
F_GETFLF_SETFL 获得或设置文件状态标志
F_GETOWNF_SETOWN 获得或设置异步I/O所有权
F_GETLKF_SETLK 或 `F_SETLKW ` 获得或设置记录锁


其中, F_GETFLF_SETFL 用来获取或设置文件状态标志,即文件的打开和关闭中提到的 O_APPENDO_NONBLOCK 等标志位。如需设置,将值传入第三个参数。


F_GETOWNF_SETOWN 用来获取或设置接受 SIGIOSIGURG 信号的进程ID组ID


如果 cmd 和锁操作有关,则第三个参数的类型为 struct flock* ,其定义如下:

struct flock {
  ……
  short l_type;     /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */
  short l_whence;   /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */
  off_t l_start;    /* Starting offset for lock */
  off_t l_len;      /* Number of bytes to lock */
  pid_t l_pid;      /* PID of process blocking our lock (F_GETLK only) */
}点击复制复制失败已复制


flock 结构体成员如下所示:

成员 含义
l_type F_RDLCK:读取锁(共享锁)
F_WRLCK:写入锁(排斥锁)
F_UNLCK:解锁
l_start 加锁区域在文件中的相对偏移量(字节),与l_whence值一起决定加锁区域的起始位置
l_whence SEEK_SET:加锁区域为文件的开始处
SEEK_CUR:加锁区域为文件的当前位置
SEEK_END:加锁区域为文件的末尾处
l_len 加锁区域的长度
l_pid 具有阻塞当前进程的锁,其持有的进程的进程号存放在l_pid中,仅由F_GETLK返回
目录
相关文章
VSPD虚拟串口软件安装及使用
VSPD虚拟串口软件安装及使用
3110 0
|
12月前
|
SQL 关系型数据库 MySQL
MySQL如何排查和删除重复数据
该文章介绍了在MySQL中如何排查和删除重复数据的方法,包括通过组合字段生成唯一标识符以及使用子查询和聚合函数来定位并删除重复记录的具体步骤。
868 2
|
SQL 关系型数据库 MySQL
关系型数据库mysql跨平台兼容性
【6月更文挑战第13天】
706 4
|
存储 机器学习/深度学习 算法
如何准确的估计llm推理和微调的内存消耗
最近发布的三个大型语言模型——Command-R+ (104B参数), Mixtral-8x22b (141B参数的MoE模型), 和 Llama 3 70b (70.6B参数)——需要巨大的内存资源。推理时,Command-R+需193.72GB GPU RAM,Mixtral-8x22B需262.63GB,Llama 370b需131.5GB。激活的内存消耗根据序列长度、批大小等因素变化。文章详细介绍了计算这些模型内存需求的方法,并探讨了如何通过量化、优化器优化和梯度检查点减少内存使用,以适应微调和推理。
1894 0
|
JavaScript 前端开发 API
vue、vuex、vue-router初学导航配合elementui及vscode快捷键
vue、vuex、vue-router初学导航配合elementui及vscode快捷键
367 0
|
传感器 5G 人机交互
基于51单片机的简易电子秤
基于51单片机的简易电子秤
|
算法
【MATLAB】史上最全的11种数字信号滤波去噪算法全家桶
【MATLAB】史上最全的11种数字信号滤波去噪算法全家桶
5805 0
【MATLAB】史上最全的11种数字信号滤波去噪算法全家桶
|
监控 NoSQL 数据可视化
1分钟快速实现Redis数据对比
通过NineData可以快速、高效完成Redis差异数据对比。NineData提供了配置简单、高效和安全的数据对比服务,能在1分钟内完成800万个key的数据对比,并生成详细的对比报告。与传统对比方式相比,NineData具有简单易用、强劲性能、完善的功能和可视化界面等优势。此外,NineData还支持多种数据库的结构和数据对比,并拥有丰富的数据源支持和动态监测功能,以确保数据的质量和稳定性。
318 2
1分钟快速实现Redis数据对比
|
Java Maven
idea、解决、maven、多moudle项目、多个root问题
idea、解决、maven、多moudle项目、多个root问题
537 0