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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/161522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Pytorch从零开始构建RNN

在这篇文章中&#xff0c;我们将了解 RNN&#xff08;即循环神经网络&#xff09;&#xff0c;并尝试通过 PyTorch 从头开始​​实现其中的部分内容。是的&#xff0c;这并不完全是从头开始&#xff0c;因为我们仍然依赖 PyTorch autograd 来计算梯度并实现反向传播&#xff0c…

Apache访问控制

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

Django(九、cookie与session)

文章目录 一、cookie与session的介绍HTTP四大特性 cookiesession Django操作cookie三板斧基于cookie的登录功能 一、cookie与session的介绍 在讲之前我们先来回忆一下HTTP的四大特性 HTTP四大特性 1.基于请求响应 2.基于TIC、IP作用于应用层上的协议 3.无状态 保存…

二叉查找(排序)树你需要了解一下

简介 二叉排序树&#xff08;Binary Sort Tree&#xff09;&#xff0c;又称二叉查找树&#xff08;Binary Search Tree&#xff09;&#xff0c;亦称二叉搜索树&#xff0c;是一种重要的数据结构。 它有以下特性&#xff1a; 若左子树不空&#xff0c;则左子树上所有结点的…

目标检测YOLO系列从入门到精通技术详解100篇-【图像处理】目标检测

目录 几个高频面试题目 如何在超大分辨率的图片中检测目标? 1当超大分辨率图像邂逅目标检测任务 2You Only Look Twice

边缘计算多角色智能计量插座 x 资产显示标签:实现资产追踪与能耗管理的无缝结合

越来越多智慧园区、智慧工厂、智慧医院、智慧商业、智慧仓储物流等企业商家对精细化、多元化智能生态应用场景的提升&#xff0c;顺应国家节能减排、环保的时代潮流&#xff0c;设计一款基于融合以太网/WiFi/蓝牙智能控制的智能多角色插座应运而生&#xff0c;赋予智能插座以遥…

大数据学习(23)-hive on mapreduce对比hive on spark

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…

uniapp实现表单弹窗

uni.showModal({title: 删除账户,confirmColor:#3A3A3A,cancelColor:#999999,confirmText:确定,editable:true,//显示content:请输入“delete”删除账户,success: function (res) {console.log(res)if(res.confirm){if(res.contentdelete){console.log(123123123213)uni.setSto…

PCIE链路训练-状态跳转1

A&#xff1a;12ms超时&#xff0c;或者再任何lane上检测到Electrical Idle Exit&#xff1b; B&#xff1a; 1.发送“receiver detection”之后没有一个lane的接收逻辑被rx检测到 2.不满足条件c&#xff0c;比如两次detection出现差别&#xff1b; C&#xff1a;发送端在没…

凸优化基础与应用

诸神缄默不语-个人CSDN博文目录 文章目录 1. 线性规划用SciPy求解 2. 二次规划3. 半定规划4. 锥规划 凸优化是数学优化的一个重要分支&#xff0c;广泛应用于各种工程和科学领域。它的核心特征在于优化问题的目标函数和约束条件是凸的&#xff0c;这使得找到全局最优解变得可行…

Ps:背景橡皮擦工具抠图实例

背景橡皮擦工具 Background Eraser Tool由于是一个破坏性的工具&#xff08;直接删除像素&#xff09;而少被人使用。 其实&#xff0c;它不仅是一个功能强大的抠图工具&#xff0c;也是可以转换为非破坏性运用的。 原图&#xff08;注&#xff1a;图片来自网络&#xff09; 效…

微软离Altman越近,离OpenAI就越远!

大数据产业创新服务媒体 ——聚焦数据 改变商业 在OpenAI这场连续剧中&#xff08;之所以说是连续剧&#xff0c;这个事情肯定没完&#xff0c;后面肯定还会出续集&#xff09;&#xff0c;让我倍感意外的是&#xff0c;Altman刚跟OpenAI分手&#xff0c;“离婚手续”都还没办…

使用Pytorch从零开始构建WGAN

引言 在考虑生成对抗网络的文献时&#xff0c;Wasserstein GAN 因其与传统 GAN 相比的训练稳定性而成为关键概念之一。在本文中&#xff0c;我将介绍基于梯度惩罚的 WGAN 的概念。文章的结构安排如下&#xff1a; WGAN 背后的直觉&#xff1b;GAN 和 WGAN 的比较&#xff1b;…

selenium新版使用find_element/find_elements函数锁定元素(替换原有find_element_by_xx)

css选择器请参考&#xff1a;网络爬虫之css选择器 原来的find_element_by_xx都被修改为find_element&#xff08;返回匹配到的第一个元素&#xff09;或find_elements&#xff08;返回全部的匹配元素&#xff09; from selenium.webdriver.common.by import By示例程序 选择…

【Q3——30min】

1、介绍一下数据库的三大范式 第一范式(1NF)&#xff1a;属性不可分割&#xff0c;即每个属性都是不可分割的原子项。(实体的属性即表中的列) 第二范式(2NF)&#xff1a;满足第一范式&#xff1b;且不存在部分依赖&#xff0c;即非主属性必须完全依赖于主属性。(主属性即主键&a…

minio集群部署(k8s内)

一、前言 minio的部署有几种方式&#xff0c;分别是单节点单磁盘&#xff0c;单节点多磁盘&#xff0c;多节点多磁盘三种方式&#xff0c;本次部署使用多节点多磁盘的方式进行部署&#xff0c;minio集群多节点部署最低要求需要4个节点&#xff0c;集群扩容时也是要求扩容的节点…

2、数仓理论概述与相关概念

1、问&#xff1a;数据仓库 建设过程中 经常会遇到那些问题&#xff1f; 模型(逻辑)重复建设 数据不一致性 维度不一致&#xff1a;命名、维度属性值、维度定义 指标不一致&#xff1a;命名、计算口径 数据不规范(字段命名、表名、分层、主题命名规范) 2、OneData数据建设核心方…

python爬虫HMAC加密案例:某企业信息查询网站

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、找出需要加密的参数 js运行 atob(‘aHR0cHM6Ly93d3cucWNjLmNvbS93ZWIvc2VhcmNoP2tleT0lRTQlQjglODclRTglQkUlQkUlRTklOUI…

飞桨——总结PPOCRLabel中遇到的坑

操作系统&#xff1a;win10 python环境&#xff1a;python3.9 paddleocr项目版本&#xff1a;2.7 1.报错&#xff1a;ModuleNotFoundError: No module named Polygon&#xff08;已解决&#xff09; 已解决所以没有复现报错内容 尝试方法一&#xff1a;直接使用pip命令安装&…

oracle rac 19.3安装补丁19.19

使用opatchauto apply DIR来进行安装 1.升级之前先备份一下GRID_HOME和ORACLE_HOME 2.现在新的opatch安装不需要先停止集群和数据库&#xff0c;在升级过程中&#xff0c;他会自动关闭和启动集群 3.先将OPatch&#xff08;P6880880&#xff09;包拷贝到$GRID_HOME和$ORACLE_HOM…