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

linux文件I/O:文件锁的概念、函数以及代码实现

文件锁是一种用来保证多个进程对同一个文件的安全访问的机制。文件锁可以分为两种类型:建议性锁和强制性锁。建议性锁是一种协作式的锁,它只有在所有参与的进程都遵守锁的规则时才有效。强制性锁是一种强制式的锁,它由内核或文件系统来强制执行,不需要进程的配合。本文将主要介绍建议性锁的实现方法和相关函数。

1. flock函数

flock函数是一种使用文件描述符来实现文件锁的方法。flock函数的功能是对一个已打开的文件描述符fd进行锁定或解锁操作,它的函数原型如下:

#include <sys/file.h>
int flock(int fd, int operation);

flock函数的用法如下:

  • 打开一个文件,获得一个文件描述符fd。
  • 调用flock函数,传入fd和想要的锁类型,例如LOCK_EX。
  • 如果成功,返回0,表示获得了锁,可以对文件进行读写操作。
  • 如果失败,返回-1,并设置errno,表示没有获得锁,可能是因为文件已经被其他进程锁定,或者其他错误发生。
  • 在完成文件操作后,调用flock函数,传入fd和LOCK_UN,释放锁,关闭文件。

flock函数的参数如下:

  • fd:一个已打开的文件描述符,必须是可读或可写的,不能是只执行的。
  • operation:一个表示锁类型的整数,可以是LOCK_SH、LOCK_EX、LOCK_UN或LOCK_NB的组合。
  • LOCK_SH:共享锁,允许多个进程同时对文件进行读操作,但不允许写操作。
  • LOCK_EX:独占锁,只允许一个进程对文件进行读写操作,其他进程都不能访问文件。
  • LOCK_UN:解锁,释放之前的锁定,允许其他进程访问文件。
  • LOCK_NB:非阻塞,如果不能立即获得锁,不会等待,而是返回错误。

flock函数的注意事项如下:

  • flock函数只能对整个文件进行锁定,不能对文件的部分区域进行锁定。
  • flock函数的锁是与进程相关的,而不是与文件描述符相关的。也就是说,如果一个进程对一个文件加了锁,那么该进程的其他文件描述符也可以访问该文件,而不受锁的影响。同样,如果一个进程关闭了一个文件描述符,那么该进程的其他文件描述符仍然保持锁定状态,直到该进程退出或显式解锁。
  • flock函数的锁是建议性的,也就是说,它只有在所有参与的进程都遵守锁的规则时才有效。如果有一个进程不使用flock函数,而是直接对文件进行读写操作,那么flock函数的锁就会失效,造成数据的不一致或损坏。

flock函数的代码示例如下:

// 一个使用flock函数的简单示例,对一个文件加上独占锁,写入一些数据,然后解锁
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/file.h>
#include <string.h>int main() {// 打开一个文件,获得一个文件描述符int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);if (fd == -1) {perror("open");exit(1);}// 调用flock函数,传入fd和LOCK_EX,加上独占锁if (flock(fd, LOCK_EX) == -1) {perror("flock");exit(1);}printf("Locked file\n");// 对文件进行写操作,写入一些数据char *data = "Hello, world!\n";if (write(fd, data, strlen(data)) == -1) {perror("write");exit(1);}printf("Wrote data to file\n");// 调用flock函数,传入fd和LOCK_UN,解锁文件if (flock(fd, LOCK_UN) == -1) {perror("flock");exit(1);}printf("Unlocked file\n");// 关闭文件close(fd);return 0;
}

2. fcntl函数

fcntl函数是一种使用文件描述符来实现文件锁的方法。fcntl函数的功能是对一个已打开的文件描述符fd进行各种控制操作。它的函数原型如下:

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

fcntl函数的用法如下:

  • 打开一个文件,获得一个文件描述符fd。
  • 调用fcntl函数,传入fd和F_GETLK,以及一个指向struct flock结构体的指针,获取文件锁的信息。
  • 如果文件没有被其他进程锁定,或者锁的类型和想要的类型不冲突,可以继续调用fcntl函数,传入fd和F_SETLK或F_SETLKW,以及一个指向struct flock结构体的指针,设置文件锁的信息。
  • 如果成功,返回0,表示获得了锁,可以对文件进行读写操作。
  • 如果失败,返回-1,并设置errno,表示没有获得锁,可能是因为文件已经被其他进程锁定,或者其他错误发生。
  • 在完成文件操作后,调用fcntl函数,传入fd和F_SETLK或F_SETLKW,以及一个指向struct flock结构体的指针,设置文件锁的类型为F_UNLCK,释放锁,关闭文件。

fcntl函数的参数如下:

  • fd:一个已打开的文件描述符,必须是可读或可写的,不能是只执行的。
  • cmd:一个表示控制操作的整数,可以是F_DUPFD、F_GETFD、F_SETFD、F_GETFL、F_SETFL、F_GETLK、F_SETLK或F_SETLKW之一。
  • F_DUPFD:复制文件描述符,返回一个新的文件描述符,指向同一个文件。
  • F_GETFD:获取文件描述符的标志,返回一个整数,表示是否设置了FD_CLOEXEC标志,该标志表示在执行exec函数时,自动关闭文件描述符。
  • F_SETFD:设置文件描述符的标志,传入一个整数,表示是否设置FD_CLOEXEC标志。
  • F_GETFL:获取文件状态标志,返回一个整数,表示文件的访问模式和其他标志,例如O_RDONLY、O_WRONLY、O_APPEND等。
  • F_SETFL:设置文件状态标志,传入一个整数,表示文件的访问模式和其他标志,例如O_RDONLY、O_WRONLY、O_APPEND等。
  • F_GETLK:获取文件锁的信息,传入一个指向struct flock结构体的指针,返回该结构体的内容,表示文件是否被其他进程锁定,以及锁的类型、起始位置、长度和持有者等信息。
  • F_SETLK:设置文件锁,传入一个指向struct flock结构体的指针,表示要设置的锁的类型、起始位置、长度等信息,如果成功,返回0,表示获得了锁,如果失败,返回-1,并设置errno,表示没有获得锁,可能是因为文件已经被其他进程锁定,或者其他错误发生。
  • F_SETLKW:设置文件锁,与F_SETLK类似,但是如果不能立即获得锁,会阻塞等待,直到获得锁或者被信号中断。
  • arg:一个可选的参数,根据cmd的不同,可以是一个整数、一个指针或者省略。如果是一个整数,表示要设置的标志或文件描述符。如果是一个指针,表示要传入或返回的struct flock结构体的地址。如果省略,表示不需要传入任何参数。

fcntl函数的注意事项如下:

  • fcntl函数可以对文件的部分区域进行锁定,而不是整个文件。这可以通过设置struct flock结构体的l_whence、l_start和l_len字段来实现。l_whence表示锁的起始位置的参考点,可以是SEEK_SET(文件开头)、SEEK_CUR(当前位置)或SEEK_END(文件结尾)。l_start表示锁的起始位置的偏移量,可以是正数、负数或零。l_len表示锁的长度,如果是正数,表示从起始位置向后锁定的字节数,如果是负数,表示从起始位置向前锁定的字节数,如果是零,表示从起始位置到文件结尾的所有字节。
  • fcntl函数的锁是与文件描述符相关的,而不是与进程相关的。也就是说,如果一个进程对一个文件加了锁,那么该进程的其他文件描述符不能访问该文件,而受锁的影响。同样,如果一个进程复制了一个文件描述符,那么复制的文件描述符也会继承锁的状态,直到所有的文件描述符都关闭或显式解锁。
  • fcntl函数的锁是建议性的,也就是说,它只有在所有参与的进程都遵守锁的规则时才有效。如果有一个进程不使用fcntl函数,而是直接对文件进行读写操作,那么fcntl函数的锁就会失效,造成数据的不一致或损坏。

fcntl函数的代码示例如下:

// 一个使用fcntl函数的简单示例,对一个文件的前10个字节加上共享锁,读取数据,然后解锁
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>int main() {// 打开一个文件,获得一个文件描述符int fd = open("test.txt", O_RDONLY);if (fd == -1) {perror("open");exit(1);}// 定义一个struct flock结构体,表示要设置的锁的信息struct flock lock;lock.l_type = F_RDLCK; // 共享锁lock.l_whence = SEEK_SET; // 文件开头lock.l_start = 0; // 起始位置lock.l_len = 10; // 长度// 调用fcntl函数,传入fd和F_SETLK,以及lock的地址,设置文件锁if (fcntl(fd, F_SETLK, &lock) == -1) {perror("fcntl");exit(1);}printf("Locked file\n");// 对文件进行读操作,读取前10个字节的数据char buf[11]; // 定义一个缓冲区,多留一个字节存放'\0'if (read(fd, buf, 10) == -1) {perror("read");exit(1);}buf[10] = '\0'; // 添加字符串结束符printf("Read data from file: %s\n", buf); // 打印读取的数据// 调用fcntl函数,传入fd和F_SETLK,以及lock的地址,设置文件锁的类型为F_UNLCK,解锁文件lock.l_type = F_UNLCK; // 解锁if (fcntl(fd, F_SETLK, &lock) == -1) {perror("fcntl");exit(1);}printf("Unlocked file\n");// 关闭文件close(fd);return 0;
}

相关文章:

linux文件I/O:文件锁的概念、函数以及代码实现

文件锁是一种用来保证多个进程对同一个文件的安全访问的机制。文件锁可以分为两种类型&#xff1a;建议性锁和强制性锁。建议性锁是一种协作式的锁&#xff0c;它只有在所有参与的进程都遵守锁的规则时才有效。强制性锁是一种强制式的锁&#xff0c;它由内核或文件系统来强制执…...

MySQL数据库系统教程

目录 基础篇 通用语法及分类 DDL&#xff08;数据定义语言&#xff09; 数据库操作 表操作 DML&#xff08;数据操作语言&#xff09; 添加数据 更新和删除数据 DQL&#xff08;数据查询语言&#xff09; 基础查询 条件查询 聚合查询&#xff08;聚合函数&#xff0…...

这样写postman实现参数化,阿里p8都直呼牛逼

什么时候会用到参数化 比如&#xff1a;一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块&#xff1a;正确的用户名&#xff0c;密码 成功&#xff1b;错误的用户名&#xff0c;正确的密码 失败 postman实现参数化 在实际的接口测试中&#xff0c;部分参数…...

【Qt-25】控件篇

一、comboBox控件 1、获取item数量 ui->comboBox_2->count(); 2、根据索引值获取文本 ui->comboBox->itemText(i); 3、调整当前显示文本内容 ui->comboBox->setCurrentIndex(j); 4、添加item ui->comboBox->addItem("");//添加一个内…...

《算法通关村——反转字符串中的单词问题解析》

《算法通关村——反转字符串中的单词问题解析》 151. 反转字符串中的单词 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接…...

C++使用Tensorflow2.6训练好的模型进行预测

要在C语言中调用训练好的TensorFlow模型,需要使用TensorFlow C API。 https://tensorflow.google.cn/install/lang_c?hl=zh-cnten TensorFlow 提供了一个 C API,该 API 可用于为其他语言构建绑定。该 API 在 c_api.h 中定义,旨在实现简洁性和一致性,而不是便利性。 下载…...

5-1 Java 网络编程

第1关&#xff1a;URL类与InetAddress类 任务描述 本关任务&#xff1a;了解网络编程基础知识。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.URL&#xff1b;2.InetAddress。 URL 统一资源定位符&#xff08;Uniform Resource Locator&#xff0c;缩…...

汇编-CALL和RET指令

CALL指令调用一个过程&#xff0c; 使处理器从新的内存位置开始执行。过程使用RET(从过程返回) 指令将处理器转回到该过程被调用的程序点上。 CALL指令的动作&#xff1a; 1.将CALL指令的下一条指令地址压栈(作为子过程返回的地址) 2.将被调过程的地址复制到指令指针寄存器E…...

STM32_5(中断)

中断系统 中断&#xff1a;在主程序运行过程中&#xff0c;出现了特定的中断触发条件&#xff08;中断源&#xff09;&#xff0c;使得CPU暂停当前正在运行的程序&#xff0c;转而去处理中断程序&#xff0c;处理完成后又返回原来被暂停的位置继续运行中断优先级&#xff1a;当…...

docker 部署hbase 并且java Api连接

首先先运行容器 docker run -d --name hbase -p 2181:2181 -p 16010:16010 -p16000:16000 -p 16020:16020 -p 16030:16030 harisekhon/hbase2.在本机的hosts中注册docker的id 因为docker内部集成了其他环境而其他环境 中的ip是docker id 所以需要在hosts中转换 192.168.80.120…...

EasyExcel listener无法通过Autowired注入xxMapper

easyexcel listener无法通过Autowired注入xxMapper 文章目录 easyexcel listener无法通过Autowired注入xxMapperbug记录&#xff1a;解决方案&#xff1a;easyexcel 使用例子controllerServiceImpllistener bug记录&#xff1a; productMapper注入一直为null,而procureDetailM…...

Android Spannable 使用​注意事项

1、当前示例中间的 "评论"&#xff0c;使用SpannableStringBuilder实现&#xff0c;点击评论会有高亮效果加粗&#xff0c;但再点击其它Bar时无法恢复默认样式。 2、因为SpannableString或SpannableStringBuilder中的效果是叠加的&#xff0c;恢复默认样式需要先移除…...

Apache访问控制

服务器相关的访问控制 Options指令 Options指令是Apache服务器配置文件中的一个重要指令,它可以用于控制特定目录启用哪些服务器特性。Options指令可以在Apache服务器的核心配置、虚拟主机配置、特定目录配置以及.htaccess文件中使用。 以下是一些常用的服务器特性选项: N…...

二、类与对象(二)

8 this指针 8.1 this指针的引入 我们先来定义一个日期的类Date&#xff1a; #include <iostream> using namespace std; class Date { public:void Init(int year, int month, int day){_year year;_month month;_day day;}void Print(){cout << _year <&l…...

Pytorch从零开始实战10

Pytorch从零开始实战——ResNet-50算法实战 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——ResNet-50算法实战环境准备数据集模型选择开始训练可视化模型预测总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c…...

设计模式-单例模式实战

目录 一、引言二、适用场景三、代码实战饿汉式单例模式懒汉式单例模式双重检查锁定单例模式静态内部类单例模式 四、实际应用举例Runtime解析 五、结论 一、引言 单例模式是一种创建型设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;且提供全局访问点以访问该实例…...

requests库出现AttributeError问题的修复与替代方法

在使用App Engine时&#xff0c;开发者们通常会面临需要发送爬虫ip请求的情况&#xff0c;而Python中的requests库是一个常用的工具&#xff0c;用于处理爬虫ip请求。然而&#xff0c;在某些情况下&#xff0c;开发者可能会遇到一个名为AttributeError的问题&#xff0c;特别是…...

opencv-2D直方图

cv2.calcHist() 是 OpenCV 中用于计算直方图的函数。它可以计算一维或多维直方图&#xff0c;用于分析图像中像素值的分布。 基本的语法如下&#xff1a; hist cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])参数说明&#xff1a; images:…...

读像火箭科学家一样思考笔记06_初学者之心

1. 专业化是目前流行的趋势 1.1. 通才&#xff08;generalist&#xff09;是指博而不精之人 1.2. 懂得的手艺越多&#xff0c;反而会家徒四壁 1.2.1. 希腊谚语 1.3. 这种态度代价很大&#xff0c;它阻断了不同学科思想的交融 2. 组合游戏 2.1. 某个行业的变革可能始于另一…...

中职组网络安全 Server-Hun-1.img Server-Hun-2.img

一串密码 smbuser用户和密码登录ssh还是失败提示需要密钥&#xff0c;尝试ftp登录成功 发现密钥存放在.ssh/下&#xff0c;在kali上生成一个密钥&#xff0c;通过上传到.ssh/下&#xff0c;将其替换掉 使用kali生成密钥 登录成功,但是无法拿到root目录下的flag 获取root用户权限…...

【入门实战】5分钟上手 ai-light-report:用自然语言驱动你的第一张智能报表

ai-light-report 是一个基于大语言模型&#xff08;LLM&#xff09;的轻量级开源报表系统&#xff0c;支持通过自然语言交互自动理解数据库语义并生成 SQL&#xff0c;快速产出可视化的报表。本文将手把手带你从零开始&#xff0c;搭建并体验这个报表工具。 Github项目开源仓库…...

BFloat16指令集解析与机器学习优化实践

1. BFloat16指令集概述与核心价值BFloat16&#xff08;Brain Floating Point 16&#xff09;是专为机器学习设计的16位浮点格式&#xff0c;由Google Brain团队于2018年提出。与传统FP16相比&#xff0c;BFloat16保留了与FP32相同的8位指数位&#xff0c;仅将尾数位从23位缩减到…...

通过curl命令快速测试Taotoken大模型api连通性与功能

通过curl命令快速测试Taotoken大模型API连通性与功能 1. 准备工作 在开始测试之前&#xff0c;请确保您已具备以下条件&#xff1a;一个有效的Taotoken API Key&#xff0c;该Key可在Taotoken控制台中创建。同时确认您的系统已安装curl工具&#xff0c;这是大多数Linux/macOS…...

kodustech/cli:模块化命令行工具集的设计哲学与工程实践

1. 项目概述&#xff1a;一个面向开发者的现代化命令行工具集如果你和我一样&#xff0c;每天的工作都离不开终端&#xff0c;那你肯定对命令行工具又爱又恨。爱的是它的高效和强大&#xff0c;一个命令就能完成图形界面里需要点半天鼠标的操作&#xff1b;恨的是&#xff0c;不…...

终极DVWA靶场定制指南:5步快速开发自定义漏洞模块

终极DVWA靶场定制指南&#xff1a;5步快速开发自定义漏洞模块 【免费下载链接】DVWA Damn Vulnerable Web Application (DVWA) 项目地址: https://gitcode.com/gh_mirrors/dv/DVWA Damn Vulnerable Web Application (DVWA) 是一款广泛使用的Web安全学习平台&#xff0c;…...

Python 爬虫数据处理:半结构化网页数据智能抽取模板

前言 在互联网数据采集场景中&#xff0c;严格遵循 XML、JSON 规范的全结构化数据占比相对有限&#xff0c;绝大多数公开网页内容均以半结构化形态呈现。半结构化数据区别于规整的数据库表格、标准接口 JSON 数据&#xff0c;具备固定排版逻辑、重复标签层级、统一内容排布规律…...

基于规则引擎的自动化决策框架:从原理到内容审核实战

1. 项目概述与核心价值最近在梳理一些自动化决策和结果预测的项目时&#xff0c;一个名为joncaris/outcome-engine的开源项目引起了我的注意。乍一看这个标题&#xff0c;你可能会联想到一个复杂的机器学习平台或者一个臃肿的企业级系统。但实际深入后&#xff0c;我发现它更像…...

2026年API中转网关选型指南:以稳定性与兼容性为锚点

开发 AI 应用时&#xff0c;调用链路常常成为“卡脖子”环节&#xff0c;比如网络波动导致超时、成本失控以及更换供应商时需要大量修改代码等问题。不过&#xff0c;使用“API 中转站/聚合网关”可以在很大程度上缓解这些问题&#xff0c;但前提是要选对类型。本文将基于稳定性…...

5大平台数据采集难题如何破解?MediaCrawler一站式解决方案详解

5大平台数据采集难题如何破解&#xff1f;MediaCrawler一站式解决方案详解 【免费下载链接】MediaCrawler-new 项目地址: https://gitcode.com/GitHub_Trending/me/MediaCrawler-new 面对小红书、抖音、快手、B站、微博这五大主流社交媒体平台的数据采集需求&#xff0…...

【仅开放30天】2026临床R认证训练营:涵盖R包CRAN审核规范、REDCap API实时对接、区块链存证日志模块

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;2026临床R认证训练营全景导览 2026临床R认证训练营是面向医学研究者、生物统计师与临床数据科学家的高阶实践型培训项目&#xff0c;聚焦R语言在真实世界证据&#xff08;RWE&#xff09;、CDISC标准&a…...